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