2014-02-19 4 views
9

Я ссылался на this Документация Oracle. При попытке выполнить следующее,Присвоение значения плавающего значения двойному значению

public static void main(String args[]){ 

    float f = 1.1f; 
    double df = 1.1f; 

    System.out.println("f=" + f); 
    System.out.println("df=" + df); 

    f = 1.5f; 
    df = 1.5f; 
    System.out.println("f=" + f); 
    System.out.println("df=" + df); 
} 

Выход

f = 1.1 
df = 1.100000023841858 
f = 1.5 
df = 1.5 

Почему вторая строка вывода показывает приблизительное значение. Но не для четвертой линии. Как рассчитывается значение?

+0

BTW '1.1f' - это« плавающий »литерал, назначая его двойному, может вводить в заблуждение. –

+0

Первое, что просто не показывает вам, что оно имеет такое же приблизительное значение. Http://floating-point-gui.de/ – zapl

+2

'' '' '' '' '' это '1.500000000000000', нули пропущены – mangusta

ответ

4

Разница в том, что 1.5 может быть представлен точно в двух экземплярах, тогда как 1.1 не может быть представлен точно.

Это из-за периодических цифр, любая (неприводимая) дробь, где знаменатель имеет простой коэффициент, который не встречается в базе, требует бесконечного числа цифр, которые периодически повторяются после определенной точки. Например, в десятичном значении 1/4, 3/5 и 8/20 являются конечными, поскольку 2 и 5 являются основными факторами 10. Но 1/3 не является конечным и не является 2/3 или 1/7 или 5/6, поскольку 3 и 7 не являются факторами 10. Фракции с основным коэффициентом 5 в знаменателе могут быть конечными в базе 10, но не в базе 2 - самый большой источник путаницы для большинства начинающих пользователей чисел с плавающей запятой.

Сжатие бесконечного числа действительных чисел в конечное число бит требует приблизительного представления. Хотя существует бесконечно много целых чисел, в большинстве программ результат целочисленных вычислений может быть храниться в 32 бит. Напротив, при любом фиксированном числе бит большинство вычислений с реальными числами будут давать величины, которые не могут быть точно представлены с использованием этого количества бит. Поэтому результат вычислений с плавающей запятой часто должен быть округлен в порядке , чтобы соответствовать его конечному представлению. Эта ошибка округления является характеристикой функции вычисления с плавающей запятой.

Проверить here для более подробной информации

+0

Как рассчитывается это приблизительное значение? – NaaN

+0

@tailorBird: Answer updated –

+0

Но он назначает 1.1f (не 1.1) оба раза. Должна ли она быть такой же постоянной? – starmole

3

Пример

Подумайте о двоичном, и что более важно, двоичном при работе с десятичным знаком.

4 2 1 . 1/2 1/4 1/8 
0 0 1 . 1  0  0 

Таким образом, как вы можете видеть, компьютер может представлять это без проблем. Теперь давайте посмотрим на 1.1.

4 2 1 . 1/2 1/4 1/8 1/16 
0 0 1 . 0  0  0  1 

На данный момент у нас есть 1.0625. Как вы можете себе представить, это довольно трудно получить 0.0475 точно, но мы можем стараться ради примера:

4 2 1 . 1/2 1/4 1/8 1/16 1/32  1/64  1/128 
0 0 1 . 0  0  0  1  1  0  0 

Теперь мы до 1.8, так что давайте продолжать идти ..

4 2 1 . 1/2 1/4 1/8 1/16 1/32  1/64  1/128 
0 0 1 . 0  0  0  1  1  1  0 

И мы должны 0.915625 ..

4 2 1 . 1/2 1/4 1/8 1/16 1/32  1/64  1/128 
0 0 1 . 0  0  0  1  1  1  1 

и мы в 0.9234375.

Объяснение

Я уверен, что вы можете увидеть, где я собираюсь с этим. Всегда будет ошибка между числом, которое вы хотите представить, и числом, которое двоичный может представлять. Иногда вам повезет, например, 1.5, а у двоичного файла нет проблем с этим. В других случаях у вас есть проблема, например, 1.1, а бинарный - как можно ближе.

0

Да, как мы знаем, представление числа в двойном точнее, чем представление того же самого в поплавке. И поплавок представлен в 32 битах, а double - в 64 бита. Таким образом, когда float присваивается двойной, число расширяется от 32 бит до 64 бит. Тогда точное число представляется точным образом. Итак, вы понимаете это немного больше?

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