2016-04-17 5 views
3

У меня есть следующий тестовый случай:Большие числа Lua печатаются неправильно

Lua 5.3.2 Copyright (C) 1994-2015 Lua.org, PUC-Rio 
> foo = 1000000000000000000 
> bar = foo + 1 
> bar 
1000000000000000001 
> string.format("%.0f", foo) 
1000000000000000000 
> string.format("%.0f", bar) 
1000000000000000000 

Это последняя строка должна быть 1000000000000000001, так как это значение bar, но по какой-то причине это не так. Это относится не только к 1000000000000000000, я еще не нашел другого номера над тем, который дает правильное значение. Может ли кто-нибудь дать объяснение, почему это происходит?

ответ

3

log2(1000000000000000000) находится между 59 и 60, что означает, что бинарное представление, что номер требует 60 бит. double -значные числа с плавающей запятой имеют только 53 бит точности, а также показатель мощности в два с 11 бит диапазона. Таким образом, чтобы сохранить это большое число в виде с плавающей запятой (это то, что вы запросили с помощью спецификатора формата %f), от шести до семи бит точности отрубают конец номера, и все это умножается на силу двух чтобы вернуть его в дальность (2 в этом случае, думаю). Отключение этих финальных бит устраняет точность, которая позволяет отличать друг от друга 1000000000000000000 и 1000000000000000001.

(Это не особенно точное описание с плавающей запятой, извинения, если мои номера или описания не являются точными.)

5

Вы форматируете число как плавающее, а не целое число. Вот что делает %.0f. В какой-то момент поплавки теряют точность. double, например, потеряет точность после примерно 16 десятичных цифр.

Если вы хотите форматировать целое как целое число, то вам нужно отформатировать его как целое, используя standard printf rules:

string.format("%i", bar)