почему статическое сравнение Float не требует значения epsilon? - PullRequest
0 голосов
/ 04 августа 2011

После проверки Float.compare (f1, f2) я обнаружил, что он сравнивает f1f2
и возвращает -1,0,1.

Затем возвращается -1,0,1, если значения -0,0, 0,0 или NAN.
Что это значит -0,0?

Я бы ожидал что-то вроде

 return (Math.abs(f1 - f2) - 0.001f) > 0) 

, где 0,001 - данное значение эпсилона.
Спасибо.

Ответы [ 2 ]

10 голосов
/ 04 августа 2011

-0.0 - это отрицательный ноль , как указано в стандарте IEEE 754 .

Если вам интересно, как может возникнуть такое значение, следующая статья поможет объяснить его: http://www.savrola.com/resources/negative_zero.html

Что касается отказа от значения эпсилона, то именно так и работает Float.compare (это точное, а не приблизительное сравнение). Ничто не помешает вам иметь другую функцию сравнения, которая делает принимает эпсилон, а выполняет приблизительное сравнение.

Как точное, так и приблизительное сравнение чисел с плавающей запятой имеют свое применение.

Что касается вашего фактического кода, он страдает от ряда проблем:

  1. это не трехстороннее сравнение, как Float.compare;
  2. не обрабатывает NaN с;
  3. обычно лучше указывать эпсилон как относительное значение, а не как абсолютное, чтобы оно масштабировалось с f1 и f2 (см. эту статью для обсуждения).

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

3 голосов
/ 04 августа 2011

Арифметика с плавающей точкой сложна. Эта статья проливает свет на основы.

-0 равно ноль со знаком :

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

...