2017-01-31 8 views
1

Если у вас есть реализация в IEEE754 совместимый с плавающей точкой, то любые сравнения с NaN является false, даже NaN == NaN, но +inf == +inf является true, почему?Что такое обоснование инф == инф в IEEE754

С моей точки зрения, было бы больше смысла говорить +inf == +inf ложно, причины:

  • Число натуральных чисел и рациональных чисел, как бесконечны, но не то же самое.

  • Если у вас есть X=1e200 и Y=1e300 (оба, X и Y является 64-разрядным удваивается), так x==y является false, но x*1e200==y*1e200 верно true (оба + инф), которая является математической некорректным.

  • Существует уже специальная обработка необходима для NaN, где X==X является false, так что не будет гораздо более реализация сложности для реализации этого +inf == +inf возвращение false. Может быть, даже меньше, потому что inf и NaN нас же «экспонентом».

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

  • X==Y является generel того true, если X-Y==0 является true, но inf-inf является NaN.

Редактировать

Как nwellnhof Allready писал: Связанный вопрос: C IEEE-Floats inf equal inf, не то же самое, там был вопрос «почему это реализация языка таким образом?», Вот вопрос " Почему стандарт определяется таким образом? ». (И оба вопроса из того же пользователя)

+1

Возможный дубликат [C IEEE-Floats inf equal inf] (http://stackoverflow.com/questions/41834621/c-ieee-floats-inf-equal-inf) –

+1

@ LưuVĩnhPhúc Как я отметил в своем ответе на связанный вопрос, я думаю, что это не дубликат. (* Почему мой код не делает то, что я ожидаю * vs. * Почему стандарт не определен, как я ожидаю *.) – nwellnhof

+0

По своей первой причине вы, кажется, путаете мощности бесконечных множеств с точками расширенного реального линия. Оба они называются «бесконечность», но они действительно не имеют ничего общего друг с другом. (И BTW, мощность множества натуральных чисел * * совпадает с мощностью множества рациональных чисел.) –

ответ

2

Вы, вероятно, должны спросить Кэхэн, основной архитектор за 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. Но мне кажется, что это мелочь.

+1

Вы все еще используете холодный метод 'define is_nan (x) (((x)! = (X)) && !((x) <0) && !((x)> 0)) ', (+ inf все еще будет больше 0 и еще не будет меньше 0), даже когда' + inf! = + inf' – 12431234123412341234123

+0

Или короче: 'define is_nan (x) (! ((x) <= 0) &&! ((x) => 0)) ' – 12431234123412341234123

+0

@ 12431234123412341234123 См. мой исправленный ответ. – nwellnhof

Смежные вопросы