У меня есть программа, которая пытается уменьшить double
до желаемого числа. На выходе я получаю NaN
.
Что NaN
значит на Java?
У меня есть программа, которая пытается уменьшить double
до желаемого числа. На выходе я получаю NaN
.
Что NaN
значит на Java?
Ответы:
Взято с этой страницы :
«NaN» означает «не число». "Nan" создается, если операция с плавающей запятой имеет некоторые входные параметры, которые приводят к тому, что операция дает неопределенный результат. Например, 0,0, деленное на 0,0, арифметически не определено. Извлечение квадратного корня из отрицательного числа также не определено.
NaN
обладает интересным свойством быть единственным «числом», которое при сравнении отличается от него самого. Поэтому общее (и во многих языках только) тест , если число x
является NaN
заключается в следующем:boolean isNaN(x){return x != x;}
i
и некоторые языки, такие как python, очень хорошо с этим справляются ... Это может быть не так в java
тебе
NaN
означает «Не число» и в основном представляет собой представление специального значения с плавающей запятой в стандарте с плавающей запятой IEE 754 . NaN обычно означает, что значение не может быть выражено действительным числом с плавающей запятой.
Преобразование приведет к получению этого значения, когда преобразуемое значение является чем-то другим, например, при преобразовании строки, которая не представляет собой число.
parseFloat()
или parseDouble
? Или что-то другое?
NaN
означает «Не число» и является результатом неопределенных операций с числами с плавающей запятой, таких как, например, деление нуля на ноль. (Обратите внимание, что, хотя деление ненулевого числа на ноль также обычно не определяется в математике, это приводит не к NaN, а к положительной или отрицательной бесконечности).
NaN
означает «Не число». Это специальное значение с плавающей запятой, которое означает, что результат операции не был определен или не может быть представлен в виде действительного числа.
Смотрите здесь для более подробного объяснения этого значения.
NaN означает не число. Он используется для обозначения любого значения, которое математически не определено. Как деление 0,0 на 0,0. Вы можете найти здесь дополнительную информацию: https://web.archive.org/web/20120819091816/http://www.concentric.net/~ttwang/tech/javafloat.htm
Разместите здесь свою программу, если вам нужна дополнительная помощь.
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));
}
}
Бежать с:
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 возвращает "Инф"?
странные операции, которые находятся на границе плюс или минус бесконечности, но дают + - бесконечность вместо NaN
1.0f / 0.0f
log(0.0f)
0.0
почти попадает в эту категорию, но, скорее всего, проблема в том, что он может переходить в плюс или минус бесконечность, поэтому он был оставлен как NaN.
если NaN является входом плавающей операции, выход также имеет тенденцию быть NaN
Есть несколько возможных значений для NaN 0x7fc00000
, 0x7fc00001
, 0x7fc00002
, хотя x86_64 , кажется, генерировать только0x7fc00000
.
NaN и бесконечность имеют одинаковое двоичное представление.
Разберем несколько из них:
nan = 0x7fc00000 = 0 11111111 10000000000000000000000
positive_inf = 0x7f800000 = 0 11111111 00000000000000000000000
negative_inf = 0xff800000 = 1 11111111 00000000000000000000000
| | |
| | mantissa
| exponent
|
sign
Исходя из этого, мы подтверждаем, что указывает IEEE754:
NaN могут быть как положительными, так и отрицательными (верхний бит), хотя это не влияет на нормальные операции.
Протестировано в Ubuntu 18.10 amd64, OpenJDK 1.8.0_191.
Не специалист по Java, но в JS и других языках я использую это «Не число», что означает, что какая-то операция заставила его стать недействительным числом.
Это буквально означает «не число». Я подозреваю, что что-то не так с вашим процессом преобразования.
Ознакомьтесь с разделом Not A Number по этой ссылке.
Недействительное значение с плавающей запятой (например, результат деления на ноль)