2016-02-26 4 views
0

Как печатать большое двойное значение с точностью 10 на C-языке (C99)?Printf большое двойное значение с высокой точностью в C

double d1 = 1100200300400500600.0000000001; 
double d2 = 1100200300400500600.0000000001; 
double d3 = d1 + d2; 
printf("???", d3); 

Ожидайте выхода: 2200400600801001200,0000000002

+0

Я пробовал '% f' и получил' 220040060080 1001216.0000000000'. –

+0

Я бы рекомендовал использовать произвольную библиотеку точности. –

+0

'double' в типичной среде (64-разрядный IEEE754) не способен хранить такое значение с высокой точностью. – MikeCAT

ответ

2

Вам нужно использовать произвольную библиотеку точности для c.

Я собираюсь хранить целые числа, вы можете использовать GMP.

Если вы собираетесь хранить большие значения с плавающей запятой, я бы рекомендовал вам использовать MPFR, библиотеку, которая поддерживает типы с плавающей запятой. MPFR основан на GMP.

+0

Спасибо. MPFR работает точно так, как ожидалось. –

0

Это не так просто. Я предлагаю вам использовать библиотеку, например GMP. Я знаю, что это не совсем то, что вы ищете, но ответ, как я уже сказал, не так прост, как кажется.

Конечно, вы можете запрограммировать себя как операции, и это хорошая практика (если вы хотите убить некоторое время). :)

1

Вы должны проверить, хранятся ли точки с плавающей запятой в C. C99 реализует IEEE754. Это дает вам 11 бит для экспоненты и 52 бит для мантиссы. Это только те 52 бита, которые вы можете использовать для представления числа. Экспонент сообщает вам, где будет плавающая точка.

Вы просто не можете хранить такое большое количество с заданной точностью в двойном размере.

+0

C99 не указывает IEEE754. Он поддерживает его использование. – chux

+0

@chux: Правда, но практически каждая реализация C99 использует поплавки IEEE. –

+0

@Peter Šilon: Я думаю, вы имеете в виду, что вы просто не можете хранить *, что многие цифры * в двойном. Само число не слишком велико, просто количество цифр. –

1

Код OP не точно присвоение значения воспринимаемому. double может представлять только конечный набор чисел. Он будет использовать ближайший представляемый double. Обычно double может точно представлять , по крайней мере первые 15 значения десятичных цифр, или 110020030040050xxxx.xxxx

1100200300400500600.0000000001 лежит между двумя double:
1100200300400500480 и
1100200300400500608.

// Add d1 to the closest representable double. This turns out to be _exactly 
//   1100200300400500608 
double d1 = 1100200300400500600.0000000001; 
double d2 = 1100200300400500600.0000000001; 

// adding those 2 result in the _exact 
//   2200400600801001216 
double d3 = d1 + d2; 

// To print to 10 decimal places 
printf("%.10f", d3); 
// 2200400600801001216.0000000000 

С типичной плавающей точкой, чтобы напечатать значение точно используйте

printf("%a\n", d3); 

Для печати double в десятичной системе счисления с sufficient accuracy различать все double, используйте

printf("%.e\n", DBL_DECIMAL_DIG - 1, d3); 
Смежные вопросы