Зачем мне 17 значащих цифр (а не 16) для представления двойника?
Может ли кто-нибудь дать мне пример числа с плавающей запятой (двойная точность), для которого требуется более 16 значащих десятичных цифр?
Я нашел в этот поток, что иногда вам нужно до 17 цифр, но я не могу найти пример такого числа (16 кажется достаточно меня).
Может ли кто-нибудь прояснить это?
Спасибо большое!
Ответы
Ответ 1
Мой другой ответ был неверным.
#include <stdio.h>
int
main(int argc, char *argv[])
{
unsigned long long n = 1ULL << 53;
unsigned long long a = 2*(n-1);
unsigned long long b = 2*(n-2);
printf("%llu\n%llu\n%d\n", a, b, (double)a == (double)b);
return 0;
}
Скомпилируйте и запустите, чтобы увидеть:
18014398509481982
18014398509481980
0
a и b являются просто 2 * (2 ^ 53-1) и 2 * (2 ^ 53-2).
Это 17-значные номера базы-10. При округлении до 16 цифр они одинаковы. Тем не менее, a и b, очевидно, нуждаются только в 53 бит точности для представления в базе-2. Поэтому, если вы берете a и b и бросаете их в два раза, вы получаете свой встречный пример.
Ответ 2
Я думаю, что парень в этом потоке ошибочен, а 16 базовых 10 цифр всегда достаточно, чтобы представлять двойной IEEE.
Моя попытка доказательства будет выглядеть примерно так:
Предположим в противном случае. Затем, обязательно, два разных числа с двойной точностью должны быть представлены одним и тем же номером базы 10-значного числа.
Но два разных числа двойной точности должны отличаться по меньшей мере одной частью в 2 ^ 53, которая больше одной части в 10 ^ 16. И никакие два числа, отличающиеся более чем одной частью в 10 ^ 16, не могли бы округлить до того же числа с базовым числом в 16 значащих цифр.
Это не является абсолютно строгим и может быть неправильным.: -)
Ответ 3
Правильный ответ - тот, что был Nemo выше. Здесь я просто вставляю простую программу Fortran, показывающую пример двух чисел, для которых требуется 17 цифр точности для печати, показывая, что нужен формат (es23.16)
для печати чисел с двойной точностью, если вы не хотите потерять любая точность:
program test
implicit none
integer, parameter :: dp = kind(0.d0)
real(dp) :: a, b
a = 1.8014398509481982e+16_dp
b = 1.8014398509481980e+16_dp
print *, "First we show, that we have two different 'a' and 'b':"
print *, "a == b:", a == b, "a-b:", a-b
print *, "using (es22.15)"
print "(es22.15)", a
print "(es22.15)", b
print *, "using (es23.16)"
print "(es23.16)", a
print "(es23.16)", b
end program
он печатает:
First we show, that we have two different 'a' and 'b':
a == b: F a-b: 2.0000000000000000
using (es22.15)
1.801439850948198E+16
1.801439850948198E+16
using (es23.16)
1.8014398509481982E+16
1.8014398509481980E+16
Ответ 4
Обходите основы одинарной и двойной точности и отвлекитесь от понятия того или иного (16-17) множества DECIMAL цифр и начните думать в (53) бинарном разряде. Необходимые примеры можно найти здесь в stackoverflow, если вы потратите некоторое время на рытье.
И я не вижу, как вы можете дать лучший ответ любому, кто дает ответ DECIMAL без квалифицированных объяснений BINARY. Этот материал прямолинейный, но это не тривиально.
Ответ 5
Самый большой непрерывный диапазон целых чисел, который может быть точно представлен двойным (8-байтовый IEEE), составляет от -2 ^ 53 до 2 ^ 53 (-9007199254740992. до 9007199254740992.). Числа -2 ^ 53-1 и 2 ^ 53 + 1 не могут быть точно представлены двойным.
Следовательно, не более 16 значащих десятичных цифр слева от десятичной точки будут точно представлять двойной в непрерывном диапазоне.