Java Float.MAX_VALUE, чтобы удвоить - PullRequest
0 голосов
/ 13 июня 2018

Вот этот код:

public class Main {
    public static void main(String[] args) {
      float a = Float.MAX_VALUE;
      double b = (double) a;
      b++;
      System.out.println(b == a);
}

и он печатает true.Кто-нибудь может объяснить, почему?

1 Ответ

0 голосов
/ 13 июня 2018

Точность double не может представить разницу между Float.MAX_VALUE и Float.MAX_VALUE+1, поэтому возвращается округленный результат.Этот округленный результат равен Float.MAX_VALUE.

Float.MAX_VALUE равен 2 128 -2 104 .(Обратите внимание, что это 2 127 + 2 126 + 2 125 +… + 2 104 . То есть это суммавсех степеней двух от 2 127 до 2 104 . В двоичном коде он имеет 24 бита, что является числом битов в значимом и 1 a float. Математически это равно 2 128 -2 104 .)

Когда вы добавляете один к этому, математический результат, конечно, 2 * 1034 128 * -2 104 + 1.Это не представимо в double, поскольку значение double составляет 53 бита, а от 2 127 до 1 - 129 бит.Вы не можете поместить биты как для 2 127 , так и для 1 в значении и double.Когда результат не может быть представлен, возвращается ближайшее представимое число.

Представляемое число чуть ниже математического результата составляет 2 128 -2 104 , а представимоечисло чуть выше математического результата составляет 2 128 -2 104 + 2 75 .(Обратите внимание, что от 2 127 до 2 75 составляет 52 бита, поэтому 2 75 - это наименьшая степень 2, которую биты в 53-битном значении имеют, а гдесамый большой бит масштабируется до 2 127 . Таким образом, мы вычислили это следующее число выше 2 128 -2 104 , добавив к нему наименьшее количество, которое подходитЗначим.) Итак, у нас есть два кандидата:

  • 2 128 -2 104 , что равно 1 от 2 128 −2 104 + 1.
  • 2 128 -2 104 + 2 75 , что составляет 2 104 + 2 75 -1 от 2 128 -2 104 + 1.

Первоеближе, поэтому он выбирается как вычисляемый результат.Таким образом, в double добавление единицы к 2 128 -2 104 дает 2 128 -2 104 .

Сноска

1 Представление двоичного числа с плавающей запятой состоит из трех частей: знак s , равный +1 или -1, значение и f , то есть число с фиксированной точкой с фиксированным числом битов и показателем степени e , так что представленное число равно s f • 2 e .Значение и можно представить как целое число с определенным числом битов, но его часто масштабируют, подстраивая показатель степени так, чтобы значение и нормальных чисел с плавающей запятой было в [1, 2).Например, 132 можно рассматривать как значение и 100001 2 раз 2 2 или как 1,00001 2 раз 2 7 .

...