Формула, которая будет выделена красным цветом, может быть использована для вычисления real number, что 64-битное значение представляет при обработке в качестве стандарта IEEE 754 с двойной. Это полезно только в том случае, если вы хотите вручную вычислить преобразование из двоичного кода в фактическое число базового 10, которое оно представляет, например, при проверке правильности реализации библиотеки C printf
.
Например, используя формулу на 0x3fd5555555555555
, х оказывается в точности 0,333333333333333314829616256247390992939472198486328125. Это реальное число, которое представляет 0x3fd5555555555555
.
#include <stdio.h>
#include <stdlib.h>
int main()
{
union {
double d;
unsigned long long ull;
} u;
u.ull = 0x3fd5555555555555L;
printf("%.55f\n", u.d);
return EXIT_SUCCESS;
}
http://codepad.org/kSithgZQ
РЕДАКТИРОВАТЬ: Как отметил Олоф, IEEE 754 двойной точности представляет значение х в уравнении, но не все действительные числа точно представима. В самом деле, лишь конечное число действительных чисел, таких как 0,5, 0,125 и 0.333333333333333314829616256247390992939472198486328125 являются точно представима, в то время как подавляющее большинство (uncountably many), включая 1/3, 0,1, 0,4 и πне.
Ключ к зная, является ли точно-представим как IEEE 754 с двойным реальным является вычисление двоичного представления действительного числа и записать его в scientific notation (например b1.001 × 2 -1 для 0.5625). Если число двоичных цифр справа от десятичной точки, исключая конечные нули, меньше или равно 52, а показатель минус один находится между -1022 и +1023, включительно, то число равно, которое точно представлено.
Давайте рассмотрим несколько примеров. Обратите внимание, что это помогает иметь калькулятор произвольной точности. Я буду использовать ARIBAS.
Число 1/64 равно 0,015625 в десятичной форме. Для того, чтобы вычислить его двоичное представление, мы можем использовать ARIBAS»decode_float
функцию:
==> set_floatprec(double_float).
-: 64
==> 1/64.
-: 0.0156250000000000000
==> set_printbase(2).
-: 0y10
==> decode_float(1/64).
-: (0y10000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000,
-0y1000101)
==> set_printbase(10).
-: 10
==> -0y1000101.
-: -69
Таким образом, 1/64 = b0.000001 или B1.0 × 2 -6 в научной нотации.
1/64 является точно представимо.
Число 1/10 = 0,1 в десятичной системе. Для того, чтобы вычислить его двоичное представление:
==> set_printbase(2).
-: 0y10
==> decode_float(1/10).
-: (0y11001100_11001100_11001100_11001100_11001100_11001100_11001100_11001100,
-0y1000011)
==> set_printbase(10).
-: 10
==> -0y1000011.
-: -67
Таким образом, 1/10 = 0,1 = b0.000 (где жирным шрифтом представляет собой повторяющуюся последовательность цифр), или b1.100 × 2 -4 в научной нотации.
1/10 не точно представимо.
отличный ответ! У многих здесь, в Stackoverflow, создается впечатление, что значения с плавающей запятой неточны. Это лишь частично верно: при использовании для представления чисел в двоичном пространстве они абсолютно и абсолютно точны, как показывает приведенный выше пример. Это когда десятичное пространство отображается на двоичный код, который мы получаем неточно, как показывает пример. Точнее, он пытается отобразить неточное десятичное значение. Возможно, для дальнейшего уточнения вы могли бы показать, как точное десятичное значение, например 0,4, отображается в двоичном виде, и мы имеем все три случая. +1 –
@Olof: Спасибо за комплимент и предложение. Я обновил свой ответ. –