Может кто-нибудь объяснить, почему:
double d = 1.0e+300;
printf("%d\n", d == 1.0e+300);
Печатает «1», как и ожидалось, на 64-битной машине, но «0» на 32-битной машине? (Я получил это, используя GCC 6.3 на Fedora 25)
Насколько мне известно, литералы с плавающей запятой имеют тип double
, и преобразование типов не происходит.
Обновление: это происходит только при использовании флага -std=c99
.
-std=c99
приводит к ожидаемому поведению примера, что странно. - person PJK   schedule 31.12.20161.0e+300
хранится в расширенной точности x87 без перехода через двойную точность, что делает его немного ближе к математически точному значению 10 ^ 300, чемd
, и приводит к сбою сравнения. Не мешало бы посмотреть сборку. (Я считаю, что стандарт разрешает это.) - person user2357112 supports Monica   schedule 31.12.2016-O0
,-O1
,-O2
,-O3
)? Если вас это утешит, в macOS Sierra 10.12.2 с использованием самодельного GCC 6.3.0 все уровни оптимизации, а также 32-битные и 64-битные компиляции дают результат 0. Насколько я могу судить, при во всяком случае, на более высоких уровнях оптимизацииprintf()
модифицируется, чтобы просто печатать0
на ассемблере — выражение равенства оценивается во время компиляции, а не во время выполнения. С-O0
(без оптимизации) генерируется гораздо больше кода для выполнения во время выполнения. - person Jonathan Leffler   schedule 01.01.2017==
для значенийfloat
илиdouble
, поскольку представление многих/большинства чисел не является точным. - person user3629249   schedule 01.01.2017==
между значениями с плавающей запятой. С таким же успехом можно сказать: «Никогда не делайте+
или*
между значениямиfloat
иdouble
, поскольку представление многих/большинства чисел неточно». - person Pascal Cuoq   schedule 01.01.2017==
между числами с плавающей запятой или двойными числами даст ожидаемые результаты. - person user3629249   schedule 03.01.2017==
даст ожидаемые результаты. Так что не используйте его. Например, программа в этом посте работает (на платформах IEEE 754, которые правильно определяютFLT_EVAL_METHOD
как 0), потому что==
дает ожидаемые результаты: blog.frama-c.com/index.php?post/2013/05/01/ . Это только один пример, я использую==
все время, как и многие программисты. Ты просто не из их числа. - person Pascal Cuoq   schedule 03.01.2017==
, но это не сработало. Во всех случаях, которые я читал (а их много), обычно это приводит к ссылке на документ stackoverflow, в котором подробно объясняется, почему==
не следует использовать при сравнении значенийfloat
иdouble
. Я поддерживаю эти пункты. В любом случае, пожалуйста, посмотрите на другой ответ на этот вопрос. - person user3629249   schedule 05.01.20170.1 + 0.2 == 0.3
. Это не работает в условиях моего предыдущего комментария и можно ожидать, что оно не сработает, даже если эти условия неверны). Также есть много вопросов, когда программист получил ошибку сегментации из-за использования*p
. Вы делаете вывод, что указатели никогда не должны использоваться? Вы ссылаетесь на «документ stackoverflow», не говоря, какой именно. поэтому невозможно объяснить, почему этот документ неверен или вы неправильно его интерпретируете. - person Pascal Cuoq   schedule 07.01.2017