Можно ли использовать удвоения для представления 64-битного числа без потери точности

Я хочу использовать lua (который внутренне использует только двойные числа) для представления целого числа, которое не может иметь ошибок округления от 0 до 2 ^ 64-1, иначе произойдут ужасные вещи.

Возможно ли это сделать?


person Kop    schedule 24.11.2009    source источник
comment
64-битная двойная точность IEEE обеспечивает ровно 53 бита мантиссы. Остальные биты предназначены для знака и экспоненты.   -  person David R Tribble    schedule 24.11.2009


Ответы (8)


Нет

По крайней мере, некоторые биты 64-битного двойного числа должны использоваться для представления экспоненты (положения двоичной точки), и, следовательно, для фактического числа доступно менее 64 бит. Так что нет, 64-битный двойник не может представлять все значения, которые могут быть представлены 64-битным целым числом (и наоборот).

person stusmith    schedule 24.11.2009
comment
Что ж, это верно, если у вас нет функции отображения между числом с плавающей запятой и целым числом 64b. Вы можете представить число как другое число с плавающей запятой. Это просто не практично :) - person viraptor; 24.11.2009
comment
Даже непрактичное решение может не сработать - например, сигнальное значение NaN (SNaN) может вызвать исключение, если оно обрабатывается в Lua (не знаю, правда ли это, но может). - person stusmith; 24.11.2009
comment
Некоторые значения для двойных чисел денормализованы — если ваш язык может перенормировать их без предупреждения, вы не сможете безопасно поместить в них 64-битную информацию. - person bdonlan; 25.11.2009

Несмотря на то, что вы получили несколько хороших ответов на свой вопрос о 64-битных типах, вам может понадобиться практическое решение вашей конкретной проблемы. Самое надежное известное мне решение — собрать Lua 5.1 с патчем LNUM (также известным как целочисленный патч Lua), который можно загрузить с LuaForge. Если вы не планируете собирать Lua из исходного кода C, существует по крайней мере одна чистая библиотека Lua, которая обрабатывает 64-битные целые числа со знаком — см. вики Lua-users.

person Community    schedule 24.11.2009

Двойник сам по себе является 64-битным типом. Однако вы теряете 1 бит для знака и 11 для экспоненты.

Так что ответ нет: это невозможно сделать.

person Toad    schedule 24.11.2009
comment
вы получаете один бит, потому что самый старший из них всегда отличен от нуля, т. е. точность равна total_bits - sign_bit - exp_bits + implicit_bit = 64 - 1 - 11 + 1 = 53 - person Christoph; 24.11.2009
comment
Я не понимаю твоего объяснения. Я понимаю, что можно «неправильно использовать» бит знака для увеличения числового диапазона. (Поэтому в основном используются отрицательные числа для увеличения положительного диапазона) - person Toad; 24.11.2009
comment
@райнер. Например, двоичное десятичное число 0,01...(еще 51 единица)...1 точно представимо в IEEE double, даже если оно имеет 53 значащих цифры. Он представлен показателем степени -2 (занимает 11 бит), знаком 0 (занимает 1 бит) и мантиссой 1...(50 1s)...1 (занимает 52 бита). Предполагается, что первый 1 нигде не хранится. Вы всегда будете выбирать показатель степени так, чтобы первый бит мантиссы был равен 1, поэтому этот первый бит просто не учитывался. Исключение составляют денормы, которые обрабатываются немного по-другому (или не обрабатываются вообще). - person Steve Jessop; 24.11.2009
comment
@reinier: у двойников IEEE 754 показатель степени равен 23, не так ли? 11-битные экспоненты предназначены для чисел с плавающей запятой. Не то, чтобы это меняет дух вашего аргумента :-) - person Arthur Reutenauer; 24.11.2009
comment
хм.. возможно ты прав. Я знаю, что Microsoft использует это: тип double содержит 64 бита: 1 для знака, 11 для экспоненты и 52 для мантиссы. Его диапазон составляет +/–1,7E308 с точностью не менее 15 цифр. источник: msdn.microsoft.com/en-us/ библиотека/e02ya398%28VS.80%29.aspx - person Toad; 24.11.2009
comment
@Arthur: двойники IEEE 754 имеют 11-битное поле экспоненты. Одинарная точность имеет 8-битное поле экспоненты. Единственное 23-битное поле в любом типе 754 с фиксированной шириной — это поле значимости числа с одинарной точностью. - person Stephen Canon; 24.11.2009

По памяти double может точно представлять 53-битное целое число со знаком.

person dreamlax    schedule 24.11.2009

Нет, вы не можете использовать Double для хранения 64-битных целых чисел без потери точности.

Однако вы можете применить патч Lua, который добавляет поддержку истинных 64-битных целых чисел в интерпретатор Lua. Примените патч LNUM к исходному коду Lua и перекомпилируйте.

person Aaron Saarela    schedule 24.11.2009

На 64 битах вы можете хранить только 2^64 разных кода. Это означает, что 64-битный тип, который может представлять 2^64 целых числа, не имеет места для представления чего-либо еще, например чисел с плавающей запятой.

Очевидно, что double может представлять множество нецелых чисел, поэтому он не может соответствовать вашим требованиям.

person Bastien Léonard    schedule 24.11.2009

IEEE 754 double не может точно представлять 64-битные целые числа. Однако он может точно представлять каждое 32-битное целое число.

person Jarek Przygódzki    schedule 02.04.2010

я ничего не знаю о lua
, но если бы вы могли понять, как выполнять побитовые манипуляции с числом с плавающей запятой на этом языке, вы могли бы теоретически создать класс-оболочку, который принимал бы ваше число в виде строки и устанавливал бы биты float в порядке, который представляет число, которое вы ему дали
более практичным решением было бы использовать какую-нибудь библиотеку bignum

person Aditya Mukherji    schedule 24.11.2009