Вопрос

У меня есть программа, которая пытается уменьшить double вплоть до желаемого числа.Результат, который я получаю, таков NaN.

Что делает NaN имеете в виду на Java?

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

Решение

Взято из эта страница:

«Нан» означает «не число». «NAN» производится, если операция с плавающей точкой имеет некоторые входные параметры, которые вызывают операцию для получения некоторого не определенного результата. Например, 0,0, разделенный на 0,0, арифметически неопределен. Взятие квадратного корня отрицательного числа также не определено.

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

NaN означает «Не число» и в основном является представлением специального значения плавающего точка в IEE 754 Плавающая точка стандартный Нан Как правило, означает, что значение - это то, что нельзя выразить с действительной с плавающей запятой.

Преобразование приведет к этому значению, когда преобразованное значение является чем-то еще, например, при преобразовании строки, которая не представляет число.

NaN означает «не число» и является результатом неопределенных операций на количестве с плавающей точкой, как, например, разделяться ноль на ноль. (Обратите внимание, что при разделении ненулевого номера на ноль также обычно не определено в математике, он не приводит к NAN, а в положительной или отрицательной бесконечности).

NaN означает «не число». Это специальное значение плавающего точка, которое означает, что результат операции не был определен или не представлен в качестве реального числа.

Видеть здесь Для более объяснения этого значения.

Нэн стоит не число. Используется для обозначения любого значения, которое математически неопределено. Как разделить 0,0 на 0,0. Вы можете посмотреть здесь для получения дополнительной информации: https://web.archive.org/web/20120819091816/http://www.concentric.net/~ttwang/tech/javafloat.htm.

Опубликуйте свою программу здесь, если вам нужна дополнительная помощь.

Nan = не число.

Означает не число. Это общее представление для невозможного числового значения во многих языках программирования.

Не Java Guy, но в JS и других языках я использую его «не число», что означает, что некоторые операции привели к тому, что она стала не действительным числом.

Это буквально означает «не число». Я подозреваю, что что-то не так с вашим процессом преобразования.

Проверьте раздел не число в Эта ссылка

Не допустимое значение плавающего точка (например, результат разделения на ноль)

http://en.wikipedia.org/wiki/nan.

Минимальный выполнимый пример

Первое, что вы должны знать, это то, что концепция NaN реализована непосредственно на аппаратном обеспечении центрального процессора.

Похоже, что все основные современные процессоры следуют IEEE 754 который определяет форматы с плавающей запятой, и NAN, которые являются просто специальными значениями с плавающей запятой, являются частью этого стандарта.

Таким образом, концепция будет очень схожей на любом языке, включая Java, который просто передает код с плавающей запятой непосредственно в центральный процессор.

Прежде чем продолжить, возможно, вы захотите сначала прочитать следующие ответы, которые я написал:

Теперь перейдем к некоторым действиям Java.Большинство представляющих интерес функций, которых нет в основном языке, находятся внутри java.lang.Float.

Nan.java

import java.lang.Float;
import java.lang.Math;

public class Nan {
    public static void main(String[] args) {
        // Generate some NaNs.
        float nan            = Float.NaN;
        float zero_div_zero  = 0.0f / 0.0f;
        float sqrt_negative  = (float)Math.sqrt(-1.0);
        float log_negative   = (float)Math.log(-1.0);
        float inf_minus_inf  = Float.POSITIVE_INFINITY - Float.POSITIVE_INFINITY;
        float inf_times_zero = Float.POSITIVE_INFINITY * 0.0f;
        float quiet_nan1     = Float.intBitsToFloat(0x7fc00001);
        float quiet_nan2     = Float.intBitsToFloat(0x7fc00002);
        float signaling_nan1 = Float.intBitsToFloat(0x7fa00001);
        float signaling_nan2 = Float.intBitsToFloat(0x7fa00002);
        float nan_minus      = -nan;

        // Generate some infinities.
        float positive_inf   = Float.POSITIVE_INFINITY;
        float negative_inf   = Float.NEGATIVE_INFINITY;
        float one_div_zero   = 1.0f / 0.0f;
        float log_zero       = (float)Math.log(0.0);

        // Double check that they are actually NaNs.
        assert  Float.isNaN(nan);
        assert  Float.isNaN(zero_div_zero);
        assert  Float.isNaN(sqrt_negative);
        assert  Float.isNaN(inf_minus_inf);
        assert  Float.isNaN(inf_times_zero);
        assert  Float.isNaN(quiet_nan1);
        assert  Float.isNaN(quiet_nan2);
        assert  Float.isNaN(signaling_nan1);
        assert  Float.isNaN(signaling_nan2);
        assert  Float.isNaN(nan_minus);
        assert  Float.isNaN(log_negative);

        // Double check that they are infinities.
        assert  Float.isInfinite(positive_inf);
        assert  Float.isInfinite(negative_inf);
        assert !Float.isNaN(positive_inf);
        assert !Float.isNaN(negative_inf);
        assert one_div_zero == positive_inf;
        assert log_zero == negative_inf;
            // Double check infinities.

        // See what they look like.
        System.out.printf("nan            0x%08x %f\n", Float.floatToRawIntBits(nan           ), nan           );
        System.out.printf("zero_div_zero  0x%08x %f\n", Float.floatToRawIntBits(zero_div_zero ), zero_div_zero );
        System.out.printf("sqrt_negative  0x%08x %f\n", Float.floatToRawIntBits(sqrt_negative ), sqrt_negative );
        System.out.printf("log_negative   0x%08x %f\n", Float.floatToRawIntBits(log_negative  ), log_negative  );
        System.out.printf("inf_minus_inf  0x%08x %f\n", Float.floatToRawIntBits(inf_minus_inf ), inf_minus_inf );
        System.out.printf("inf_times_zero 0x%08x %f\n", Float.floatToRawIntBits(inf_times_zero), inf_times_zero);
        System.out.printf("quiet_nan1     0x%08x %f\n", Float.floatToRawIntBits(quiet_nan1    ), quiet_nan1    );
        System.out.printf("quiet_nan2     0x%08x %f\n", Float.floatToRawIntBits(quiet_nan2    ), quiet_nan2    );
        System.out.printf("signaling_nan1 0x%08x %f\n", Float.floatToRawIntBits(signaling_nan1), signaling_nan1);
        System.out.printf("signaling_nan2 0x%08x %f\n", Float.floatToRawIntBits(signaling_nan2), signaling_nan2);
        System.out.printf("nan_minus      0x%08x %f\n", Float.floatToRawIntBits(nan_minus     ), nan_minus     );
        System.out.printf("positive_inf   0x%08x %f\n", Float.floatToRawIntBits(positive_inf  ), positive_inf  );
        System.out.printf("negative_inf   0x%08x %f\n", Float.floatToRawIntBits(negative_inf  ), negative_inf  );
        System.out.printf("one_div_zero   0x%08x %f\n", Float.floatToRawIntBits(one_div_zero  ), one_div_zero  );
        System.out.printf("log_zero       0x%08x %f\n", Float.floatToRawIntBits(log_zero      ), log_zero      );

        // NaN comparisons always fail.
        // Therefore, all tests that we will do afterwards will be just isNaN.
        assert !(1.0f < nan);
        assert !(1.0f == nan);
        assert !(1.0f > nan);
        assert !(nan == nan);

        // NaN propagate through most operations.
        assert Float.isNaN(nan + 1.0f);
        assert Float.isNaN(1.0f + nan);
        assert Float.isNaN(nan + nan);
        assert Float.isNaN(nan / 1.0f);
        assert Float.isNaN(1.0f / nan);
        assert Float.isNaN((float)Math.sqrt((double)nan));
    }
}

Восходящий поток GitHub.

Бегите с:

javac Nan.java && java -ea Nan

Выходной сигнал:

nan            0x7fc00000 NaN
zero_div_zero  0x7fc00000 NaN
sqrt_negative  0xffc00000 NaN
log_negative   0xffc00000 NaN
inf_minus_inf  0x7fc00000 NaN
inf_times_zero 0x7fc00000 NaN
quiet_nan1     0x7fc00001 NaN
quiet_nan2     0x7fc00002 NaN
signaling_nan1 0x7fa00001 NaN
signaling_nan2 0x7fa00002 NaN
nan_minus      0xffc00000 NaN
positive_inf   0x7f800000 Infinity
negative_inf   0xff800000 -Infinity
one_div_zero   0x7f800000 Infinity
log_zero       0xff800000 -Infinity

Итак, из этого мы узнаем несколько вещей:

  • странные операции с плавающей запятой, которые не дают никакого разумного результата, дают NaN:

    • 0.0f / 0.0f
    • sqrt(-1.0f)
    • log(-1.0f)

    сгенерировать NaN.

    В C действительно возможно запрашивать сигналы, которые должны быть вызваны при таких операциях с feenableexcept чтобы обнаружить их, но я не думаю, что это доступно в Java: Почему целочисленное деление на ноль 1/0 выдает ошибку, но с плавающей запятой 1/0.0 возвращает "Inf"?

  • странные операции, которые находятся на пределе либо плюс, либо минус бесконечности, однако дают +- бесконечность вместо NaN

    • 1.0f / 0.0f
    • log(0.0f)

    0.0 почти подпадает под эту категорию, но, вероятно, проблема в том, что оно могло перейти либо в плюс, либо в минус бесконечность, поэтому было оставлено как NaN.

  • если NaN является входным сигналом плавающей операции, то выходные данные также имеют тенденцию быть NaN

  • существует несколько возможных значений для NaN 0x7fc00000, 0x7fc00001, 0x7fc00002, хотя x86_64 , кажется , генерирует только 0x7fc00000.

  • NaN и infinity имеют аналогичное двоичное представление.

    Давайте разберем некоторые из них:

    nan          = 0x7fc00000 = 0 11111111 10000000000000000000000
    positive_inf = 0x7f800000 = 0 11111111 00000000000000000000000
    negative_inf = 0xff800000 = 1 11111111 00000000000000000000000
                                | |        |
                                | |        mantissa
                                | exponent
                                |
                                sign
    

    Исходя из этого, мы подтверждаем то, что указывает IEEE754:

    • как NaN, так и бесконечности имеют показатель == 255 (все единицы)
    • бесконечности имеют мантиссу == 0.Следовательно, возможны только две бесконечности:+ и -, различаемые по знаковому разряду
    • У НэН есть мантисса != 0.Таким образом, существует несколько возможностей, за исключением мантиссы == 0, которая равна бесконечности
  • NANS может быть как положительным, так и отрицательным (верхний бит), хотя это никак не влияет на нормальную работу

Протестировано в Ubuntu 18.10 amd64, OpenJDK 1.8.0_191.

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