2013-11-22 3 views
2

У меня есть этот образец кода:печать значение с плавающей точкой

float approx = 1234567712f; 
System.out.println(approx); 

Вместо печати «1.234567712E9» или что-то подобное он печатает «1.23456768E9». Насколько я понимаю, это как-то связано с точностью на двоичном уровне.

Сколько двоичных цифр является точностью для чисел с плавающей точкой (до и после символа запятой (",")? Не могли бы вы объяснить это простым способом, почему это происходит?

+0

http://en.wikipedia.org/wiki/Single-precision_floating-point_format – rgettman

+1

Этот вопрос задан 100 раз в разных формах. Он всегда возвращается к тому, что «значимость» 32-битного числа с плавающей запятой содержит только 23 бита. Вы не можете выразить число с большей точностью, чем одна часть в 2^24. Таким образом, в плавающей точке 2^24 + 1 == 2^24. И 2^24 ~ 16М. См. [Что должен знать каждый компьютерный ученый о плавающей запятой] (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – Floris

ответ

0

float имеет точность до 7 цифр до и после запятой. Вот почему 1234567 является правильным, а остальные 3 цифры - нет. Вы должны использовать double вместо float, если вы хотите вычислить с большими номерами

2

Число с плавающей запятой состоит из «значимого» и «экспоненты». Чтобы представить целые числа до последней нечетной цифры, показатель должен быть равен нулю. Это означает, что у вас есть 24 бит доступного (24-бит всегда 1 и, следовательно, не сохраняется), а наибольшее целое число, вы можете хранить в

0xFFFFFF == 16777215 

Если вы хотите добавить 2 к этому числу, то «точному» представительство будет

0x1000001 = 16777217 

Для хранения этого номера вам потребуется 25 бит; так что последняя цифра становится рубила, а число будет храниться в виде

0x800000 x 2^1 == 16777216 

Как числа получить больше, то «прыгать» между последовательными представимыми числами становится больше. К тому времени, когда вы доберетесь до

1234567112 == 0x4995FFC8 

Для его хранения вам понадобится 32 бита. Но у вас есть только 24 бита, поэтому он будет храниться внутри как нечто вроде

0x499600 x 2^8 (rounded to the closest number). 

= 0x49960000 = 1234567168

который является номер, который вы видели.

Смежные вопросы