Почему примитивное значение float может быть -0.0? Что это значит? Можно ли отменить эту функцию?
Когда у меня есть:
float fl;
Затем fl == -0.0
возвращает true
, а также fl == 0
. Но когда я печатаю его, он печатает -0.0
.
Почему примитивное значение float может быть -0.0? Что это значит? Можно ли отменить эту функцию?
Когда у меня есть:
float fl;
Затем fl == -0.0
возвращает true
, а также fl == 0
. Но когда я печатаю его, он печатает -0.0
.
Потому что Java использует стандарт IEEE для арифметики с плавающей точкой (IEEE 754), который определяет -0.0
и когда его следует использовать.
Представляемое наименьшее число не имеет 1 бита в субнормальном значении и называется положительным или отрицательным нулем, определяемым знаком. Фактически он представляет округление до нуля чисел в диапазоне от нуля до наименьшего представимого ненулевого числа того же знака, поэтому у него есть знак и почему его обратные +Inf или -Inf также имеют знак,
Вы можете обойти вашу конкретную проблему, добавив 0.0
например
Double.toString(value + 0.0);
См.: Сложные числа Java с плавающей точкой
Операции с отрицательным нулем
...
(-0.0) + 0,0 → 0,0
-
"-0.0" создается, когда операция с плавающей запятой приводит к отрицательному числу с плавающей запятой, настолько близкому к 0, что оно не может быть нормально представлено.
как примитивное значение float может быть -0.0?
числа с плавающей запятой сохраняются в памяти с помощью стандарта IEEE 754, что означает ошибки округления. Вы никогда не сможете сохранить число с плавающей точкой бесконечной точности с ограниченными ресурсами.
Вам не следует проверять, является ли число с плавающей запятой == другому, т.е. никогда не писать такой код:
if (a == b)
где a
и b
- float. Из-за ошибок округления эти два числа могут храниться как разные значения в памяти.
Вы должны определить точность, с которой хотите работать:
private final static double EPSILON = 0.00001;
а затем проверьте точность, необходимую вам
if (Math.abs(a - b) < epsilon)
Итак, в вашем случае, если вы хотите проверить, что число с плавающей запятой равно нулю в заданной точности:
if (Math.abs(a) < epsilon)
И если вы хотите отформатировать номера при выводе их в графический интерфейс, вы можете взглянуть на следующую статью и NumberFormat class.
Тип с плавающей точкой в Java описан в JLS: 4.2.3 Типы, форматы и значения с плавающей запятой.
Он говорит об этих специальных значениях:
(...) Каждое из четырех наборов значений включает в себя не только конечные ненулевые значения, которые приписываются ему выше, но также значения NaN и четыре значения положительный нуль, отрицательный нуль, положительный бесконечности и отрицательной бесконечности. (...)
И есть важные заметки о них:
Положительный нуль и отрицательный нуль сравниваются равными; таким образом, результат выражения 0.0 == - 0.0 является истинным, а результат 0.0 > -0.0 является ложным. Но другие операции могут различать положительный и отрицательный ноль; например, 1.0/0.0 имеет значение положительной бесконечности, а значение 1.0/-0.0 - отрицательная бесконечность.
Вы не можете "отменить" эту функцию, это часть того, как работают поплавки.
Подробнее о отрицательном ноте, посмотрите на Подписанный нуль в Википедии.
Если вы хотите проверить, какой "вид" нулевого значения у вас есть, вы можете использовать тот факт, что:
(new Float(0.0)).equals(new Float(-0.0))
есть false
(но действительно, 0.0 == -0.0
).
Посмотрите здесь более подробно: Инфраструктуры чисел с плавающей запятой Java.
Из wikipedia
Стандарт IEEE 754 для арифметики с плавающей запятой (в настоящее время используется большинство компьютеров и языков программирования, поддерживающих с плавающей запятой чисел) требует как +0, так и -0. Нули можно рассматривать как вариант расширенной линии действительных чисел такой, что 1/-0 = -∞ и 1/+ 0 = + ∞, деление на ноль составляет только undefined для ± 0/± 0 и ± ∞/± ∞.
Я не думаю, что вы можете или должны отменить эту функцию. Вы не должны сравнивать числа с плавающей точкой с символом == из-за ошибок точности.
Хорошая статья о том, как обрабатываются числа точек с плавающей точкой в java/computers. http://www.artima.com/underthehood/floating.html
btw: это настоящая боль в компьютерах, когда 2.0 - 1.0 может произвести 0.999999999999, что не равно 0,1. Это может быть особенно легко наткнуться на валидации формы javascript.