Джава:Добавление Double.MIN_NORMAL к двойному числу не меняет число.

StackOverflow https://stackoverflow.com//questions/24050149

Вопрос

Я думал, что MIN_NORMAL — это значение, которое можно добавить к «обычному» двойному значению, и число изменится.Например.добавьте Double.MIN_NORMAL к 0,1d, и вы получите значение, отличное от 0,1d, однако мое понимание неверно:

public static void test(double val) {
    if (val == (val - Double.MIN_NORMAL*1e50d))
        System.out.printf("val == (val - Double.MIN_NORMAL*1e50d) for val=%.20f\n", val);
    else
        System.out.printf("val != (val - Double.MIN_NORMAL*1e50d) for val=%.20f\n", val);
}

Что производит:

test(0.0d);
> val != (val - Double.MIN_NORMAL*1e50d) for val=0.00000000000000000000

test(1.0d);
> val == (val - Double.MIN_NORMAL*1e50d) for val=1.00000000000000000000

test(0.1d);
> val == (val - Double.MIN_NORMAL*1e50d) for val=0.10000000000000000000

Кто-нибудь, пожалуйста, объясните, что здесь противоречит моей логике: даже если я добавлю MIN_NORMAL раз 1e50d, я все равно получу то же число.

Я проверил двоичные представления и обнаружил, что 1 * Double.MIN_NORMAL отличается от 2 * Double.MIN_NORMAL, но вычитание их из чего-либо, кроме нуля, не меняет исходное число.

Это было полезно?

Решение

MIN_NORMAL является, как говорит Javadoc, лишь наименьшим нормализованным double ценить.Но это не значит, что это что-то вроде 1 для intс:Для значений с плавающей запятой просто существует нет стандартный «eps», который вы можете добавить, чтобы перейти к следующему представимому значению — «eps» всегда зависит от показателя степени данного значения с плавающей запятой.Вот почему их называют плавающий баллы, в конце концов :)

Однако Java 1.6+ обеспечивает Math.nextAfter() который возвращает для любого заданного double, следующий или предыдущий представимый double.

В старых версиях Java вы всегда можете возиться с Double.doubleToLongBits(), увеличивая или уменьшая его результат и конвертируя обратно на Double.longBitsToDouble();это дает вам следующую или предыдущую репрезентативную величину double ценить -- в большинстве случаев:есть несколько особых случаев (NaN, бесконечные значения), поэтому новичкам с плавающей запятой это не рекомендуется :)

Другие советы

Двойной имеет ограниченную точность.Min_normal 2e-1022.Он будет отброшен, если число вы не добавите его, также в балкете 2E-1000.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top