Гарантируется ли для любого конечного значения с плавающей запятой, что 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 равно ВСЕГДА NaN .

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

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

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


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

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

8
задан Community 23 May 2017 в 12:10
поделиться

1 ответ

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

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

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

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

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

3
ответ дан 5 December 2019 в 23:12
поделиться
Другие вопросы по тегам:

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