В этом случае изменение, которое вы наблюдаете, не имеет особого отношения к преобразованию из 8-байтового формата в 4-байтовый формат. Ваш PI
будет отличаться от 3.14
независимо от того, объявляете ли вы его float
или double
. Значение 3.14
невозможно точно представить в бинарном формате с плавающей запятой. 4, 8 или 1234 байтов все еще недостаточно для построения точного двоичного представления 3.14
, так как в традиционном двоичном формате с плавающей запятой это представление бесконечно длинное.
Точное бинарное представление 3.14
является
11.001000111101011100001010001010001111010... = 11.0(01000111101011100001010001)
означает, что 01000111101011100001010001
часть повторяется снова и снова до бесконечности. Когда вы используете float
, все изображение усекается (или округляется) до float
, тогда как в случае double
оно усекается в размере double
. По этой причине любой тип с плавающей запятой будет представлять только 3.14
. double
будет точнее, чем float
, но все же не совсем точно.
Это округление именно то, что получается 3.14
в 3.1400001049041748046875
в случае float
и в 3.140000000000000124344978758017532527446747
в случае double
(результаты от GCC компилятора). Ваш компилятор может использовать другую стратегию округления, приводящую к несколько иным значениям.
Если кто-то голосует за этот вопрос, то просьба указать ваши комментарии .. –
Если не ошибаюсь, это преобразование определяется реализацией. – VoidPointer
Вы, вероятно, захотите прочитать [this] (http://www.validlab.com/goldberg/paper.pdf). – devnull