JAVA Double.MIN_VALUE, IEEE 754 и калькулятор Google? - PullRequest
0 голосов
/ 24 февраля 2019

Кажется, что наименьшее ненулевое число, которое калькулятор Google может вычислить, равно 2 ^ -1023.Т.е. 2 ^ -1024 равно 0.

В JAVA Double.MIN_VALUE равно 2 ^ -1074.

При чтении о JAVA Double.MIN_VALUE здесь и в Интернете есть много упоминаний IEEE 754но на самом деле ни один из них не говорит, что 2 ^ -1074 - это наименьшее ненулевое число, определенное в IEEE 754.

Итак, мои вопросы:

  1. Как работает JAVA Double.MIN_VALUEотносятся к определению IEEE 754 наименьшего ненулевого числа?Есть ли такая вещь вообще?
  2. Почему калькулятор Google не может вычислять меньшие числа, чем 2 ^ -1023, когда, по-видимому, есть такие числа?(Я знаю, что люди не используют их каждый день, но, тем не менее, языки программирования позволяют это)
  3. В JAVA, если Double.MIN_VALUE == 4.9E-324, то почему (Double.MIN_VALUE + Double.MIN_VALUE) == 1.0E-323, а не 9.8E-324, учитывая, что (4.9E-5 + 4.9E-5) == 9.8E-5?
  4. Сколько я должен добавить в Double.MIN_VALUE, чтобы сделать его равным нулю?

Вот программа, которую я создал для этих вопросов:

public class Lecture {
    public static void main(String[] args) {

        double min = Double.MIN_VALUE;
        double max = Double.MAX_VALUE;
        double minPlusOne = min + 0.0001;
        System.out.println("Min + 1: " + minPlusOne);
        System.out.println("Double.MIN_VALUE: " + min);
        System.out.println("Double.MIN_VALUE: " + max);
        double myMin = Math.pow(2, -1074);
        System.out.println("2^-1074: " + myMin);
        System.out.println("Double.MIN_VALUE == 2^-1074: "  + (min == myMin));
        System.out.println();

        System.out.println("Changed Min:" + (min + min));

        double a = 4.9E-5;
        double b = a + a;
        System.out.println(b);

    }
}

РЕДАКТИРОВАТЬ: Как и просили, удаляя последующие вопросы.

Ответы [ 3 ]

0 голосов
/ 24 февраля 2019

Как JAVA Double.MIN_VALUE соотносится с определением IEEE 754 наименьшего ненулевого числа?Есть ли такая вещь вообще?

Вы должны внимательно прочитать хороший учебник по числам FP, например , что должен знать каждый программист об арифметике с плавающей запятой .Минимальное значение «нормальных» чисел составляет 2 ^ -1023.Но IEEE-754 также имеет «субнормальные» (или ненормальные) числа, минимальное значение которых равно 2 ^ -1074.Эти цифры могут быть меньше, но с большой потерей точности.

Почему калькулятор Google не может вычислять меньшие числа, чем 2 ^ -1023, когда, по-видимому, есть такие числа?(Я знаю, что люди не используют их каждый день, но, тем не менее, языки программирования допускают это.)высокая временная стоимость (например, задержка оператора Pentium для нормальных чисел составляет ~ 5, но может быть> 100, если результат или один операнд является ненормальным).Это может быть причиной того, что Google не поддерживает субнормалы (но это всего лишь гипотеза).Библиотеки и аппаратные средства FP имеют возможность рассматривать субнормальные числа как ноль.

В JAVA, если Double.MIN_VALUE == 4.9E-324, то почему (Double.MIN_VALUE + Double.MIN_VALUE) == 1.0E-323, а не 9.8E-324, учитывая, что (4.9E-5 + 4.9E-5) == 9.8E-5?

Печатное значение округляется и отображается в двоичном виде.Точное значение целой части 2 ^ -1023 имеет гораздо больше десятичных знаков, чем 4,9.и то же самое для его двойника.Это вопрос отображения.

Сколько я должен добавить к Double.MIN_VALUE, чтобы сделать его равным нулю?

Просто вычтите это для себя.

0 голосов
/ 24 февраля 2019

Вместо «чтения через Интернет» вы могли бы ввести эти поисковые термины в любую поисковую систему:

IEEE 754 1074

И вы могли бы найтиследующие статьи в Википедии, которые хорошо это объясняют:

https://en.wikipedia.org/wiki/IEEE_754-1985#Double_precision:

Двойная точность Числа двойной точности занимают 64 бита.С двойной точностью:

  • Ближайшие к нулю положительные и отрицательные числа (представленные денормализованным значением со всеми 0 в поле Exp и двоичным значением 1 в поле Fraction) равны

    ± 2 ^ −1074 ≈ ± 4.94066 × 10 ^ −324

  • Ближайшие к нулю положительные и отрицательные нормализованные числа (представлены двоичным значением> 1 в поле Expи 0 в поле дроби) равны

    ± 2 ^ −1022 ≈ ± 2.22507 × 10 ^ −308

  • Конечные положительные и конечные отрицательные> числа, наиболее удаленные от нуля(представлено значением с 2046 в поле Exp и всеми 1 в поле дроби):

    ± (1-2 ^ −53) × 2 ^ 1024 ≈ ± 1.79769 × 10 ^ 308

https://en.wikipedia.org/wiki/IEEE_754#Basic_and_interchange_formats:

Обратите внимание, что в приведенной выше таблице минимальные показатели приведены для нормальных чисел;специальное представление субнормальных чисел позволяет представлять даже меньшие числа (с некоторой потерей точности).Например, наименьшее положительное число, которое может быть представлено в двоичном коде, равно 2 ^ -1074 (потому что 1074 = 1022 + 53 - 1).

0 голосов
/ 24 февраля 2019
  1. Вместо «чтения здесь и через Интернет» достаточно взглянуть на Javadoc:

    Константа, содержащая наименьшее положительное ненулевое значение типаdouble ... а также равно Double.longBitsToDouble(0x1L).

    Т.е. его последний бит равен 1, а остальные равны 0.

  2. 2 ^ -1023 на самом деле не минимальное значение, вы можете получить Double.MIN_VALUE как (2^-1023)/2^51.Понятия не имею, почему разработчики Google сделали 2^-1024, вернув 0, вам нужно их спросить.

  3. Double.MIN_VALUE, как задокументировано, 2 ^ -1074.Это не равно 4,9 * 10 ^ -324, это просто напечатано в соответствии с спецификацией Double#toString.Округление для Double.MIN_VALUE и 2*Double.MIN_VALUE происходит в разных направлениях.

  4. -Double.MIN_VALUE, как и для любого другого Double d, который вы добавили бы -d.

...