Преобразование целого числа в строку в QUIK 8.8+

Страницы: 1
RSS
Преобразование целого числа в строку в QUIK 8.8+
 
В связи с переходом биржи мы дождались 19 знаков.

Уважаемые разработчики и коллеги, может кто подскажет, почему результат разный и что надо подставить в string.format, чтобы он стал одинаковый? Как вы понимаете, необходимо, чтобы Номер заявки или сделки в виде строки всегда был нормальным числом, идентичным самому числу.
Код
a=9952336732254970146
message(string.format("%.f",a).." "..tostring(a))
Результат: 9952336732254969856 9.952336732255e+18
Код
a=1952336732254970146   
message(string.format("%.f",a).." "..tostring(a))

Результат: 1952336732254970112 1952336732254970146
Код
a=9952336732254970146
message(string.format("%.d",a).." "..tostring(a))
Результат: "bad argument #2 to 'format' (number has no integer representation)"
 
Для кучи добавлю еще вариант
Код
a=1952336732254970146
message(string.format("%.d",a).." "..tostring(a))
Результат: 1952336732254970146 1952336732254970146

Все вроде хорошо, но 3-й результат предыдущего сообщения все портит.
 
https://forum.quik.ru/forum10/topic5119/
10й вопрос.
 
тут надо заметить что метод работать только для чисел меньше 9223372036854775807
Цитата
Sergey Gorokhov написал:
https://forum.quik.ru/forum10/topic5119/
10й вопрос.
 
Цитата
Sergey Gorokhov написал:
тут надо заметить что метод работать только для чисел меньше 9223372036854775807
Цитата
Sergey Gorokhov написал:
 https://forum.quik.ru/forum10/topic5119/  
10й вопрос.

Что еще предложите?

Код
local function tostringEX(x)
return tostring(math.tointeger(x) or x)
end

a=1952336732254970146
message(tostringEX(x).." "..tostring(a))

Результат: nil 1952336732254970146
 
Пока получается, что лучше всего работает это:
Код
a=9152336732254970146
message(string.format("%.d",a).." "..tostring(a))

Результат: 9152336732254970146 9152336732254970146
 
а можно подробнее про ошибку.
у меня 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
 
Цитата
Александр М написал:
Пока получается, что лучше всего работает это:
Код
  a =  9152336732254970146 
 message ( string.format ( "%.d" ,a) .. " " .. tostring(a))  

Результат: 9152336732254970146 9152336732254970146
данный вариант всем хорош, НО, если вдруг число стало не целым, то:
Код
a=9152336732254970146.0
message(string.format("%.d",a).." "..tostring(a))

Результат: 9152336732254969856 9.152336732255e+18
 
Тему можно закрывать, как результат проверки работает криво, поэтому до преобразования типа доводить нельзя иначе все числа едут.
 
Попробуйте использовать паттерн "%.0f".
 
Цитата
Nikolay написал:
Попробуйте использовать паттерн "%.0f".
Пробовал, он аналогичен самому первому примеру.
 
Цитата
Александр М написал:
Что еще предложите?
Предлагаем быть более внимательным в передаче параметров в функцию.
от куда у Вас возьмется параметр "x" если есть только переменная "a"?
 
Цитата
Sergey Gorokhov написал:
Цитата
Александр М написал:
Что еще предложите?
Предлагаем быть более внимательным в передаче параметров в функцию.
от куда у Вас возьмется параметр "x" если есть только переменная "a"?
Согласен, моя ошибка. Правда проблему не решило, если произошло изменение типа:
Код
local function tostringEX(x)
return tostring(math.tointeger(x) or x)
end

a=1952336732254970146.0
message(tostringEX(a).." "..tostring(a))

Результат: 1952336732254970112 1.952336732255e+18

Если изменения типа не было, то там и tostring() прекрасно работает.
 
Цитата
Александр М написал:
проблему не решило, если произошло изменение типа
При преобразовании в double произошла потеря точности. Первоначальное значение никакими ухищрениями уже не вернуть.
Код
a = 1952336732254970112
b = a + 0.0
print(a == b)
Надо делать так, как надо. А как не надо - делать не надо.
 
Выше пример преобразования числа без потери точности (поэтому format с ним справляется)
А это с потерей точности:
Код
a = 1952336732254970146
b = a + 0.0
print(a == b)
Надо делать так, как надо. А как не надо - делать не надо.
 
Только сейчас увидел, что Вы пытаетесь сделать.
lua не может преобразовать double с таким числом цифр как 9152336732254970146.0

4-ое издание Programming in Lua, глава 4 (https://www.moys.gov.iq/upload/common/Programming_in_Lua%2C_4th_ed._%282017%29_.pdf)

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, то его не будет.
 
Цитата
Nikolay написал:
Только сейчас увидел, что Вы пытаетесь сделать.
lua не может преобразовать double с таким числом цифр как 9152336732254970146.0

4-ое издание Programming in Lua, глава 4 ( https://www.moys.gov.iq/upload/common/Programming_in_Lua%2C_4th_ed._%282017%29_.pdf )

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
----------------
что не так?
 
Цитата
nikolz написал:
Цитата
Александр М написал:
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, чтобы он стал одинаковый? Как вы понимаете, необходимо, чтобы Номер заявки или сделки в виде строки всегда был нормальным числом, идентичным самому числу.
Код
  a =  9952336732254970146 
 message ( string.format ( "%.f" ,a) .. " " .. tostring(a))  
Результат: 9952336732254969856 9.952336732255e+18
Код
  a =  1952336732254970146    
 message ( string.format ( "%.f" ,a) .. " " .. tostring(a))
  

Результат: 1952336732254970112 1952336732254970146
Код
  a =  9952336732254970146 
 message ( string.format ( "%.d" ,a) .. " " .. tostring(a))
  
Результат: "bad argument #2 to 'format' (number has no integer representation)"
Правильно я понял, что Вы где надо и не надо лепили к числам ".0"
В итоге получали переполнение разрядной сетки мантиссы, т к в отличии от целого числа на нее в 64 битах меньше места?
Ну батенька, надо учить мат.часть.
 
Цитата
nikolz написал:
Цитата
Александр М написал:
В связи с переходом биржи мы дождались 19 знаков.

Уважаемые разработчики и коллеги, может кто подскажет, почему результат разный и что надо подставить в string.format, чтобы он стал одинаковый? Как вы понимаете, необходимо, чтобы Номер заявки или сделки в виде строки всегда был нормальным числом, идентичным самому числу.
 
Код
    a  =    9952336732254970146  
  message  ( string.format (  "%.f"  ,a)  ..   " "   ..  tostring(a))    
 Результат: 9952336732254969856 9.952336732255e+18
 
Код
    a  =    1952336732254970146     
  message  ( string.format (  "%.f"  ,a)  ..   " "   ..  tostring(a))
    
 
Результат: 1952336732254970112 1952336732254970146
 
Код
    a  =    9952336732254970146  
  message  ( string.format (  "%.d"  ,a)  ..   " "   ..  tostring(a))
    
 Результат: "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.
 
Цитата
Sergey Gorokhov написал:
https://forum.quik.ru/forum10/topic5119/
10й вопрос.
Касательно предложения в 10 вопросе tostring(math.tointeger(x) or x), попробуйте данное решение на числе tostring(math.tointeger(1.16*100) or 1.16*100)
Увидите, что не работает.
 
Nikolay,
Допустим. А зачем делать арифметические операции с номером заявки/сделки?
 
Не зачем, наверно. Но если использовать единый подход для форматирования, то он должен быть единым.

С другой стороны, не очень понятно зачем вообще применять форматирование для чисел типа integer. tostring итак их выводит корректно.
Если только вы не гарантируете тип integer для номера заявки. Но тогда это будет уже другой разговор.
 
Nikolay,
Тема про "math.tointeger" возникла из-за появления ".0", к большим числам она не относится.
Автор хотел исследовать вопрос и ему было предложено такое решение для ознакомления

Цитата
Nikolay написал:
С другой стороны, не очень понятно зачем вообще применять форматирование для чисел типа integer. tostring итак их выводит корректно. Если только вы не гарантируете тип integer для номера заявки. Но тогда это будет уже другой разговор
применять форматирование не нужно, в той же ветке сказано что tostring будет работать с большими числами, собственно Вы и сами это говорили.

По сути, с числами есть две проблемы, первая это появление ".0" у любых чисел, и эта проблема чинится предложенной функцией.
Вторая это некорректное преобразование 19ти значных дробных чисел в строку и решения для нее нет.
Но в практике, 19 ти значные числа есть только в номерах заявок/сделок, а для них нет никаких практических задач которые могли бы привести к преобразованию их в дробное число.
Страницы: 1
Читают тему
Наверх