Гарантируется ли для любого конечного значения с плавающей запятой, что x - x == 0?

Значения с плавающей запятой неточны, поэтому нам редко следует использовать строгое числовое равенство при сравнениях. Например, в Java это печатает false (как показано на ideone.com):

System.out.println(.1 + .2 == .3);
// false

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

System.out.println(Math.abs(.1 + .2 - .3) < .00000000000001);
// true

Вопрос в том, могут ли некоторые операции давать точный результат. Мы знаем, что для любого не конечного значения с плавающей запятой x (т. Е. NaN или бесконечности) x - x равно < em> ВСЕГДА NaN.

Но если x конечно, гарантировано ли что-нибудь из этого?

  1. x * -1 == -x
  2. x - x == 0

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


Как бы то ни было, я думаю (и здесь я могу ошибаться) ответ - ДА! Я думаю, что все сводится к тому, для какого-либо конечного IEEE-754 значение с плавающей запятой, его аддитивная инверсия всегда точно вычислима. Так как, например, float и double имеет один выделенный бит только для знака, похоже, это так , поскольку для нахождения аддитивной инверсии требуется только перевернуть знаковый бит (т. е. значащий оставить нетронутым).

Связанные вопросы


person polygenelubricants    schedule 30.08.2010    source источник
comment
Этот вопрос немного задевает мой мозг, поэтому я не могу внести свой вклад, но я только что проверил вашу ссылку на ideone.com ... этот сайт выглядит круто!   -  person BG100    schedule 30.08.2010
comment
возможный дубликат Is есть ли значение x с плавающей запятой, для которого xx == 0 ложно?   -  person Gabe    schedule 30.08.2010
comment
Ого! Я голосую за то, чтобы закрыть свой вопрос из-за обмана.   -  person polygenelubricants    schedule 30.08.2010


Ответы (2)


Хотя x - x может дать вам -0, а не истину 0, -0 сравнивается как равное 0, поэтому вы будете уверены, что любое конечное число минус само по себе будет сравниваться с нулем.

См. Есть ли значение x с плавающей запятой, для которого xx == 0 является ложным? для получения дополнительных сведений.

person Gabe    schedule 30.08.2010

Оба равенства гарантируются IEEE 754 с плавающей запятой, потому что результаты как x-x, так и x * -1 представляются точно как числа с плавающей запятой той же точности, что и x. В этом случае, независимо от режима округления, точные значения должны быть возвращены соответствующей реализацией.

РЕДАКТИРОВАТЬ: по сравнению с примером .1 + .2.

Вы не можете добавить .1 и .2 в IEEE 754, потому что вы не можете представить их для передачи в +. Сложение, вычитание, умножение, деление и извлечение квадратного корня возвращают уникальное значение с плавающей запятой, которое, в зависимости от режима округления, находится непосредственно под, сразу вверху, ближайшим к правилу обработки связей, ..., результат операции над те же аргументы в R. Следовательно, когда результат (в R) представляется как число с плавающей запятой, это число автоматически становится результатом независимо от режима округления.

Тот факт, что ваш компилятор позволяет вам писать 0.1 как сокращение для другого представимого числа без предупреждения, ортогонален определению этих операций. Например, когда вы пишете - (0.1), - является точным: он возвращает прямо противоположное своему аргументу. С другой стороны, его аргумент не 0.1, а double, который ваш компилятор использует вместо него.

Короче говоря, другая часть причины, по которой операция x * (-1) является точной, заключается в том, что -1 может быть представлен как double.

person Pascal Cuoq    schedule 30.08.2010
comment
Отчасти причина в том, что вычитание и умножение, а также сложение, деление и извлечение квадратного корня являются одними из основных операций, для которых оптимальные результаты требуются стандартом IEEE 754. - person Pascal Cuoq; 30.08.2010
comment
Следовательно, определение оптимального требует разъяснения, потому что вы можете утверждать, что, возможно, это оптимально для .1 + .2 == .3, но я думаю, что это false во всех реализациях IEEE-754 double (если я не упускаю какие-то другие вопросы). - person polygenelubricants; 30.08.2010