Вы, вероятно, должны спросить Кэхэн, основной архитектор за IEEE 754-1985, но this answer проливает некоторый свет на эту тему:
более важно , в то время, когда NaN был формализован в арифметике 8087, не было предиката isnan(); необходимо было предоставить программистам удобные и эффективные средства обнаружения значений NaN, которые не зависят от языков программирования, предоставляющих нечто вроде isnan(), которое может занять много лет. Я процитирую собственное письмо Кахана на эту тему:
Если бы не было способа избавиться от NaNs, они были бы столь же бесполезны, как и Неопределенные на CRAY; как только кто-то столкнулся, расчет лучше всего прекратить, а не продолжиться на неопределенное время до окончательного вывода. Вот почему некоторые операции над NaN должны доставлять результаты, отличные от NaN. Какие операции? ... Исключениями являются предикаты C «x == x» и «x!= x ", которые равны соответственно 1 и 0 для каждого бесконечного или конечного числа x [курсив добавил], но наоборот, если x не является числом (NaN); они обеспечивают единственное простое исключающее различие между NaN и числами [выделено мной] на языках, которым не хватает слова для NaN и предиката IsNaN (x).
Если +inf
не был равен +inf
, тест x != x
для NaNs не будет работать, потому что было бы поймать бесконечности, а также. Еще в 1985 году C программист мог бы написать:
#define is_nan(x) ((x) != (x))
#define is_pos_inf(x) ((x) == 1.0/0.0)
#define is_neg_inf(x) ((x) == -1.0/0.0)
С inf != inf
, вам нужно что-то вроде:
#define is_nan(x) (!((x) >= 0) && !((x) <= 0))
#define is_pos_inf(x) ((x) != (x) && (x) > 0.0)
#define is_neg_inf(x) ((x) != (x) && (x) < 0.0)
Я вижу вашу точку, и я согласен, что наличие +inf != +inf
является более правильным из чисто математической точки зрения. Но ИМО, это не перевешивает практические соображения.
[устанавливает] натуральных чисел и рациональных чисел, оба являются бесконечными, но [не имеют] [мощности].
Это не имеет особого отношения к вычислениям с плавающей точкой.
Если у вас есть X = 1e200 и Y = 1e300 (оба, X и Y являются 64-бит удваивается), так что х == у ложна, но х * 1e200 == у * 1e200 верно верно (оба являются + inf), что является математически неверным.
Математика с плавающей запятой изначально математически неверна. Вы можете найти много конечные с плавающей запятой, X
, Y
, Z
, с X != Y
, где X <op> Z == Y <op> Z
.
Я не вижу никакого преимущества или любого приложения, требующего, чтобы + inf == + inf. Вы не должны сравнивать любые значения с плавающей запятой с == в любом случае.
Я также не вижу приложения, которое потребует +inf != +inf
.
X == Y является [...] истинным, если X-Y == 0 истинно, но inf-inf является NaN.
Это на самом деле несоответствие, которое может решить +inf != +inf
. Но мне кажется, что это мелочь.
Возможный дубликат [C IEEE-Floats inf equal inf] (http://stackoverflow.com/questions/41834621/c-ieee-floats-inf-equal-inf) –
@ LưuVĩnhPhúc Как я отметил в своем ответе на связанный вопрос, я думаю, что это не дубликат. (* Почему мой код не делает то, что я ожидаю * vs. * Почему стандарт не определен, как я ожидаю *.) – nwellnhof
По своей первой причине вы, кажется, путаете мощности бесконечных множеств с точками расширенного реального линия. Оба они называются «бесконечность», но они действительно не имеют ничего общего друг с другом. (И BTW, мощность множества натуральных чисел * * совпадает с мощностью множества рациональных чисел.) –