Сообщение Re[2]: printf double от 13.04.2019 7:53
Изменено 13.04.2019 8:08 netch80
Re[2]: printf double
Здравствуйте, kov_serg, Вы писали:
BFE>>Как распечатать double со всей возможной точностью?
_>Очень просто https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%BE_%D0%B4%D0%B2%D0%BE%D0%B9%D0%BD%D0%BE%D0%B9_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D1%81%D1%82%D0%B8
_>53*ln(2)/ln(10)=15.95
_>соответственно "%.16g" (16 значащащих цифр) более чем достаточно.
Нет, недостаточно. Нужно 17, а не 16. Доказательство:
Запускаем:
Вообще, откуда вы взяли 16, совершенно непонятно. По отношению к double, которое IEEE754 binary 64-bit portable float, есть две константы:
1. Сколько цифр десятичного текстового представления сохранится при любом значении десятичного порядка при конверсии в двоичное представление и обратно (берётся самое короткое из десятичных, которое конвертируется в то же двоичное представление), при умолчательном округлении. Это значение равно 15.
2. Сколько цифр десятичного представления нужно, чтобы произвольное число в двоичном виде перевести в десятичное представление и затем из него — в двоичное, чтобы значение сохранилось. Это число равно 17.
Для сравнения, для single AKA float AKA IEEE754 binary 32-bit portable float — тут будет 6 и 9 — их разность на 1 больше. Для single, очень мало значений, что сохранится только 6 цифр, а не 7, но они таки есть, и это одна из причин критики формата и стандарта в целом: сделали бы significand не 23 бита, а 24 — размах порядка бы уменьшился (10^19 вместо 10^38), но точность была бы лучше формализуемой. (Я с этой критикой не согласен, но она достаточно активно звучит.)
BFE>>Как распечатать double со всей возможной точностью?
_>Очень просто https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%BE_%D0%B4%D0%B2%D0%BE%D0%B9%D0%BD%D0%BE%D0%B9_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D1%81%D1%82%D0%B8
_>53*ln(2)/ln(10)=15.95
_>соответственно "%.16g" (16 значащащих цифр) более чем достаточно.
Нет, недостаточно. Нужно 17, а не 16. Доказательство:
#include <stdio.h>
int main() {
double f1 = 0.3;
double f2 = 0.1 * 3;
printf("%.16g\n", f1);
printf("%.16g\n", f2);
printf("%.17g\n", f1);
printf("%.17g\n", f2);
}
Запускаем:
$ ./td
0.3
0.3
0.29999999999999999
0.30000000000000004
Вообще, откуда вы взяли 16, совершенно непонятно. По отношению к double, которое IEEE754 binary 64-bit portable float, есть две константы:
1. Сколько цифр десятичного текстового представления сохранится при любом значении десятичного порядка при конверсии в двоичное представление и обратно (берётся самое короткое из десятичных, которое конвертируется в то же двоичное представление), при умолчательном округлении. Это значение равно 15.
2. Сколько цифр десятичного представления нужно, чтобы произвольное число в двоичном виде перевести в десятичное представление и затем из него — в двоичное, чтобы значение сохранилось. Это число равно 17.
Для сравнения, для single AKA float AKA IEEE754 binary 32-bit portable float — тут будет 6 и 9 — их разность на 1 больше. Для single, очень мало значений, что сохранится только 6 цифр, а не 7, но они таки есть, и это одна из причин критики формата и стандарта в целом: сделали бы significand не 23 бита, а 24 — размах порядка бы уменьшился (10^19 вместо 10^38), но точность была бы лучше формализуемой. (Я с этой критикой не согласен, но она достаточно активно звучит.)
Re[2]: printf double
Здравствуйте, kov_serg, Вы писали:
BFE>>Как распечатать double со всей возможной точностью?
_>Очень просто https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%BE_%D0%B4%D0%B2%D0%BE%D0%B9%D0%BD%D0%BE%D0%B9_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D1%81%D1%82%D0%B8
_>53*ln(2)/ln(10)=15.95
_>соответственно "%.16g" (16 значащащих цифр) более чем достаточно.
Нет, недостаточно. Нужно 17, а не 16. Доказательство:
Запускаем:
Вообще, откуда вы взяли 16, совершенно непонятно. По отношению к double, которое IEEE754 binary 64-bit portable float, есть две константы:
1. Сколько цифр десятичного текстового представления сохранится при любом значении десятичного порядка при конверсии в двоичное представление и обратно (берётся самое короткое из десятичных, которое конвертируется в то же двоичное представление), при умолчательном округлении. Это значение равно 15. Константа — DBL_DIG из <float.h>.
2. Сколько цифр десятичного представления нужно, чтобы произвольное число в двоичном виде перевести в десятичное представление и затем из него — в двоичное, чтобы значение сохранилось, при умолчательном округлении. Это число равно 17. Константа — DBL_DECIMAL_DIG из <float.h>.
Для сравнения, для single AKA float AKA IEEE754 binary 32-bit portable float — тут будет 6 и 9 (FLT_DIG, FLT_DECIMAL_DIG соответственно) — их разность на 1 больше. Для single, очень мало значений, что сохранится только 6 цифр, а не 7, но они таки есть, и это одна из причин критики формата и стандарта в целом: сделали бы significand не 23 бита, а 24 — размах порядка бы уменьшился (10^19 вместо 10^38), но точность была бы лучше формализуемой. (Я с этой критикой не согласен, но она достаточно активно звучит.)
BFE>>Как распечатать double со всей возможной точностью?
_>Очень просто https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%BE_%D0%B4%D0%B2%D0%BE%D0%B9%D0%BD%D0%BE%D0%B9_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D1%81%D1%82%D0%B8
_>53*ln(2)/ln(10)=15.95
_>соответственно "%.16g" (16 значащащих цифр) более чем достаточно.
Нет, недостаточно. Нужно 17, а не 16. Доказательство:
#include <stdio.h>
int main() {
double f1 = 0.3;
double f2 = 0.1 * 3;
printf("%.16g\n", f1);
printf("%.16g\n", f2);
printf("%.17g\n", f1);
printf("%.17g\n", f2);
}
Запускаем:
$ ./td
0.3
0.3
0.29999999999999999
0.30000000000000004
Вообще, откуда вы взяли 16, совершенно непонятно. По отношению к double, которое IEEE754 binary 64-bit portable float, есть две константы:
1. Сколько цифр десятичного текстового представления сохранится при любом значении десятичного порядка при конверсии в двоичное представление и обратно (берётся самое короткое из десятичных, которое конвертируется в то же двоичное представление), при умолчательном округлении. Это значение равно 15. Константа — DBL_DIG из <float.h>.
2. Сколько цифр десятичного представления нужно, чтобы произвольное число в двоичном виде перевести в десятичное представление и затем из него — в двоичное, чтобы значение сохранилось, при умолчательном округлении. Это число равно 17. Константа — DBL_DECIMAL_DIG из <float.h>.
Для сравнения, для single AKA float AKA IEEE754 binary 32-bit portable float — тут будет 6 и 9 (FLT_DIG, FLT_DECIMAL_DIG соответственно) — их разность на 1 больше. Для single, очень мало значений, что сохранится только 6 цифр, а не 7, но они таки есть, и это одна из причин критики формата и стандарта в целом: сделали бы significand не 23 бита, а 24 — размах порядка бы уменьшился (10^19 вместо 10^38), но точность была бы лучше формализуемой. (Я с этой критикой не согласен, но она достаточно активно звучит.)