Почему плавающий ZERO в Java может быть положительным или отрицательным? [Дубликат]

Java не поддерживает TCO на уровне компилятора, но его можно реализовать с помощью Java 8 с использованием лямбда-выражений. Он описывается Venkat Subramaniamin в «Функциональное программирование на Java».

42
задан mskfisher 11 May 2012 в 18:32
поделиться

5 ответов

Поскольку 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, которое невозможно представить нормально.

46
ответ дан OldCurmudgeon 28 August 2018 в 23:16
поделиться

Из wikipedia

Стандарт IEEE 754 для арифметики с плавающей запятой (в настоящее время используется большинством компьютеров и языков программирования, поддерживающих числа с плавающей запятой) требует как +0, так и -0. Нули можно рассматривать как вариант расширенной линии действительных чисел, так что 1 / -0 = -∞ и 1 / + 0 = + ∞, деление на ноль только неопределено для ± 0 / ± 0 и ± ∞ / ± ∞ .

Я не думаю, что вы можете или должны отменить эту функцию. Вы не должны сравнивать числа с плавающей запятой с == из-за ошибок точности.

4
ответ дан Armen Tsirunyan 28 August 2018 в 23:16
поделиться

, как примитивное значение float может быть -0.0?

числа с плавающей запятой сохраняются в памяти с использованием стандарта 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 .

16
ответ дан Darin Dimitrov 28 August 2018 в 23:16
поделиться

Тип с плавающей запятой в Java описан в JLS: 4.2.3 Типы, форматы и значения с плавающей запятой .

Он говорит об этих специальных значениях:

(...) Каждое из четырех наборов значений включает в себя не только конечные ненулевые значения, которые приписываются ему выше, но также значения NaN и четыре значения положительный ноль, отрицательный нуль, положительная бесконечность , и отрицательная бесконечность. (...)

И имеет некоторые важные заметки о них:

Положительный нуль и отрицательный нуль сравниваются равными; таким образом, результат выражения 0.0 == - 0.0 является истинным, а результат 0.0> -0.0 является ложным. Но другие операции могут различать положительный и отрицательный ноль; например, 1.0 / 0.0 имеет значение положительной бесконечности, а значение 1.0 / -0.0 - отрицательная бесконечность.

Вы не можете «отменить» эту функцию, это часть того, как float work.

Подробнее о отрицательном нуле смотрите в записи Signed zero Wikipedia.

Если вы хотите проверить, какой «вид» но у вас есть, вы можете использовать тот факт, что:

(new Float(0.0)).equals(new Float(-0.0))

- false (но действительно, 0.0 == -0.0).

Посмотрите здесь больше: Интенсивности чисел с плавающей запятой Java .

9
ответ дан Mat 28 August 2018 в 23:16
поделиться

Хорошая статья о том, как управлять номерами точек с плавающей точкой в ​​java / computers. http://www.artima.com/underthehood/floating.html

btw: это настоящая боль в компьютерах, когда 2.0 - 1.0 может произвести 0.999999999999, что не равно 1. 0 :). Это может быть особенно легко наткнуться на валидации формы javascript.

3
ответ дан ya_pulser 28 August 2018 в 23:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: