Уважаемые разработчики и коллеги, может кто подскажет, почему результат разный и что надо подставить в string.format, чтобы он стал одинаковый? Как вы понимаете, необходимо, чтобы Номер заявки или сделки в виде строки всегда был нормальным числом, идентичным самому числу.
а можно подробнее про ошибку. у меня Lua 5.3 работает корректно вот пример: a=1952336732254970146 print(a) print(tostring(a)) print(a+1) print(tostring(a+1)) ------- результат: 1952336732254970146 1952336732254970146 1952336732254970147 1952336732254970147 ---------------- что не так?
nikolz написал: а можно подробнее про ошибку. у меня Lua 5.3 работает корректно вот пример: a=1952336732254970146 print(a) print(tostring(a)) print(a+1) print(tostring(a+1)) ------- результат: 1952336732254970146 1952336732254970146 1952336732254970147 1952336732254970147 ---------------- что не так?
Внимательно посмотрите все мои варианты и сделайте ваш пример для числа 9152336732254970146
For floating-point numbers, Standard Lua uses double precision. It represents each number with 64 bits, 11of which are used for the exponent. Double-precision floating-point numbers can represent numbers withroughly 16 significant decimal digits, in a range from -10308 to 10308. (Small Lua uses single-precisionfloats, with 32 bits. In this case, the range is from -1038 to 1038, with roughly seven significant decimaldigits.)
Any integer up to 2^53 (which is 9007199254740992) has an exact representation as a double-precisionfloating-point number. Integers with larger absolute values may lose precision when converted to a float.
Поэтому если число имеет тип math.type = integer, то до 2^53 (9007199254740992) нет проблем представления. А если это уже double, то его не будет.
For floating-point numbers, Standard Lua uses double precision. It represents each number with 64 bits, 11of which are used for the exponent. Double-precision floating-point numbers can represent numbers withroughly 16 significant decimal digits, in a range from -10308 to 10308. (Small Lua uses single-precisionfloats, with 32 bits. In this case, the range is from -1038 to 1038, with roughly seven significant decimaldigits.)
Any integer up to 2^53 (which is 9007199254740992) has an exact representation as a double-precisionfloating-point number. Integers with larger absolute values may lose precision when converted to a float.
Поэтому если число имеет тип math.type = integer, то до 2^53 (9007199254740992) нет проблем представления. А если это уже double, то его не будет.
Специально я не пытаюсь, я боюсь, чтобы случайно преобразования не было, иначе беда. Причем, если она случилась, то она не лечится, номер изменится.
Александр М написал: print(a)print(tostring(a))print(a+1)print(tostring(a+1))
сделал так: а=9152336732254970146 print(a) print(tostring(a)) --------------------- результат: 9152336732254970146 9152336732254970146 ---------------- что не так?
Александр М написал: print(a)print(tostring(a))print(a+1)print(tostring(a+1))
сделал так: а=9152336732254970146 print(a) print(tostring(a)) --------------------- результат: 9152336732254970146 9152336732254970146 ---------------- что не так?
Пока тип не поменялся, все tostring() работает корректно, я выше уже написал. Теперь надо следить за этим в коде, т.к. если он изменится, то преобразование числа в строку дает или неправильное значение или вообще с e+... Выше я продемонстрировал. Я в своем коде проблему решил, просто проверил все места, где смотрится или преобразовывается номера заявок или сделок.
Александр М написал: В связи с переходом биржи мы дождались 19 знаков.
Уважаемые разработчики и коллеги, может кто подскажет, почему результат разный и что надо подставить в string.format, чтобы он стал одинаковый? Как вы понимаете, необходимо, чтобы Номер заявки или сделки в виде строки всегда был нормальным числом, идентичным самому числу.
Результат: "bad argument #2 to 'format' (number has no integer representation)"
Правильно я понял, что Вы где надо и не надо лепили к числам ".0" В итоге получали переполнение разрядной сетки мантиссы, т к в отличии от целого числа на нее в 64 битах меньше места? Ну батенька, надо учить мат.часть.
Александр М написал: В связи с переходом биржи мы дождались 19 знаков.
Уважаемые разработчики и коллеги, может кто подскажет, почему результат разный и что надо подставить в string.format, чтобы он стал одинаковый? Как вы понимаете, необходимо, чтобы Номер заявки или сделки в виде строки всегда был нормальным числом, идентичным самому числу.
Результат: "bad argument #2 to 'format' (number has no integer representation)"
Правильно я понял, что Вы где надо и не надо лепили к числам ".0" В итоге получали переполнение разрядной сетки мантиссы, т к в отличии от целого числа на нее в 64 битах меньше места? Ну батенька, надо учить мат.часть.
Не правильно, я вообще ничего не лепил и у меня преобразования не было, но я в коде исторически использовал "%.f", т.к. надеялся, что если преобразование типов случайно пройдет, то в строку не добавится ".0" в конце. Код .0 не добавлял, а вот сам номер изменил даже при преобразовании целого числа в строку, о чем я и написал.
Не правильно, я вообще ничего не лепил и у меня преобразования не было, но я в коде исторически использовал "%.f", т.к. надеялся, что если преобразование типов случайно пройдет, то в строку не добавится ".0" в конце. Код .0 не добавлял, а вот сам номер изменил даже при преобразовании целого числа в строку, о чем я и написал.
вот это "%.f" и есть преобразование из целого в вещественное. В документации сказано: Стандартный Lua использует 64-битные целые (integer) и вещественные числа двойной точности (double 64-bit) В итоге у Вас 64 битное целое не умещается в 64 битное вещественное, т к для мантиссы всего 53 бита Проблема решается если целое число преобразовать в вещественное расширенной точности (long double ), но луа не поддерживает данный формат, а железо поддерживает. Поэтому если надо, то пишите свою функцию на API C.
Касательно предложения в 10 вопросе tostring(math.tointeger(x) or x), попробуйте данное решение на числе tostring(math.tointeger(1.16*100) or 1.16*100) Увидите, что не работает.
Не зачем, наверно. Но если использовать единый подход для форматирования, то он должен быть единым.
С другой стороны, не очень понятно зачем вообще применять форматирование для чисел типа integer. tostring итак их выводит корректно. Если только вы не гарантируете тип integer для номера заявки. Но тогда это будет уже другой разговор.
Nikolay, Тема про "math.tointeger" возникла из-за появления ".0", к большим числам она не относится. Автор хотел исследовать вопрос и ему было предложено такое решение для ознакомления
Цитата
Nikolay написал: С другой стороны, не очень понятно зачем вообще применять форматирование для чисел типа integer. tostring итак их выводит корректно. Если только вы не гарантируете тип integer для номера заявки. Но тогда это будет уже другой разговор
применять форматирование не нужно, в той же ветке сказано что tostring будет работать с большими числами, собственно Вы и сами это говорили.
По сути, с числами есть две проблемы, первая это появление ".0" у любых чисел, и эта проблема чинится предложенной функцией. Вторая это некорректное преобразование 19ти значных дробных чисел в строку и решения для нее нет. Но в практике, 19 ти значные числа есть только в номерах заявок/сделок, а для них нет никаких практических задач которые могли бы привести к преобразованию их в дробное число.