Преобразование целого числа в строку в 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.
Страницы: 1
Читают тему (гостей: 1)
Наверх