Подтвердить что ты не робот

Зачем мне 17 значащих цифр (а не 16) для представления двойника?

Может ли кто-нибудь дать мне пример числа с плавающей запятой (двойная точность), для которого требуется более 16 значащих десятичных цифр?

Я нашел в этот поток, что иногда вам нужно до 17 цифр, но я не могу найти пример такого числа (16 кажется достаточно меня).

Может ли кто-нибудь прояснить это?

Спасибо большое!

4b9b3361

Ответ 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 значащих десятичных цифр слева от десятичной точки будут точно представлять двойной в непрерывном диапазоне.