Почему эта программа C дает "неправильный" вывод?
#include<stdio.h>
void main()
{
float f = 12345.054321;
printf("%f", f);
getch();
}
Вывод:
12345.054688
Но вывод должен быть, 12345.054321
.
Я использую VC ++ в VS2008.
Он выдает "неправильный" ответ просто потому, что не все реальные значения можно представить в виде float (или double, если уж на то пошло). Вы получите приближенное значение, основанное на базовой кодировке.
Для представления любого реального значения, даже между 1,0x10-100 и 1,1x10-100 (действительно мизерный диапазон), вам все равно потребуется бесконечное число битов.
Значения IEEE754 с одинарной точностью имеют только 32 бита (некоторые из которых предназначены для других вещей, таких как экспонента и представления NaN/Inf) и поэтому не могут дать вам бесконечную точность. На самом деле у них доступно 23 бита, что дает точность около 224 (есть дополнительный неявный бит) или чуть больше 7 десятичных цифр (log10(224) - примерно 7,2).
Я заключил слово "неправильно" в кавычки, потому что это не на самом деле неправильно. Ошибка заключается в вашем понимании того, как компьютеры представляют числа (не обижайтесь, вы не одиноки в этом заблуждении).
Зайдите на http://www.h-schmidt.net/FloatApplet/IEEE754.html и введите свое число в поле "Десятичное представление", чтобы увидеть это в действии.
Если вы хотите получить более точное число, используйте двойные числа вместо плавающих - они имеют вдвое больше битов для представления значений (при условии, что ваша реализация C использует типы данных IEEE754 одинарной и двойной точности для float и double соответственно).
Если вам нужна произвольная точность, вам придется использовать библиотеку "bignum", например GMP, хотя это несколько медленнее, чем собственные типы, поэтому убедитесь, что вы понимаете компромиссы.
Десятичное число 12345.054321 не может быть точно представлено как float
на вашей платформе. Результат, который вы видите, является десятичным приближением к ближайшему числу, которое может быть представлено как float
.
Значения с плавающей запятой одинарной точности могут представлять только около восьми до девяти значащих (десятичных) цифр. За пределами этой точки вы видите ошибку квантования.
float
предназначены для удобства и скорости и используют двоичное представление - если вам важна точность, используйте десятичный тип.
Чтобы разобраться в проблеме, прочтите Что должен знать каждый компьютерный ученый об арифметике с плавающей запятой : http://docs.sun.com/source/806-3568 /ncg_goldberg.html
Решение можно найти в Часто задаваемых вопросах по десятичной арифметике : http://speleotrove.com/decimal/decifaq.html
Все дело в точности. Ваш номер не может быть точно сохранен в поплавке.