Посмотрите на этот фрагмент:
int main() {
double v = 1.1;
return v == 1.1;
}
При 32-битной компиляции эта программа возвращает 0, если указан -fexcess-precision=standard. Без него программа возвращает 1.
Почему такая разница? Глядя на ассемблерный код (godbolt), кажется, что с -fexcess-precision=standard gcc использует 1.1 как длинную двойную константу (он загружает константу как TBYTE >). Почему он так делает?
Сначала я подумал, что это ошибка, но нашел комментарий об ошибке gcc. Кажется, такое поведение намеренно или, по крайней мере, не является неожиданным.
Сначала я подумал, что это ошибка, но нашел комментарий об ошибке gcc.
p>
Это проблема качества связи? Я понимаю, что сравнение выполняется с использованием длинной двойной точности, но мой 1.1 не является длинным двойным литералом. Странно то, что если я приведу 1.1 при сравнении к double (который уже является двойным), проблема исчезнет.
(Еще одна странность: GCC дважды загружает и сравнивает, см. двойную инструкцию fucomip. Но он делает это даже в 64-битном режиме. Я понимаю, что в моей ссылке на godbolt оптимизация отключена, но тем не менее, в моем коде есть только одно сравнение, почему GCC сравнивает дважды?)
Вот ассемблерный код без -fexcess-precision=standard:
main:
push ebp
mov ebp, esp
and esp, -8
sub esp, 16
fld QWORD PTR .LC0
fstp QWORD PTR [esp+8]
fld QWORD PTR [esp+8]
fld QWORD PTR .LC0
fucomip st, st(1)
fstp st(0)
setnp al
mov edx, 0
fld QWORD PTR [esp+8]
fld QWORD PTR .LC0
fucomip st, st(1)
fstp st(0)
cmovne eax, edx
movzx eax, al
leave
ret
.LC0:
.long -1717986918
.long 1072798105
А вот и все:
main:
push ebp
mov ebp, esp
and esp, -8
sub esp, 16
fld QWORD PTR .LC0
fstp QWORD PTR [esp+8]
fld QWORD PTR [esp+8]
fld TBYTE PTR .LC1
fucomip st, st(1)
setnp al
mov edx, 0
fld TBYTE PTR .LC1
fucomip st, st(1)
fstp st(0)
cmovne eax, edx
movzx eax, al
leave
ret
.LC0:
.long -1717986918
.long 1072798105
.LC1:
.long -858993459
.long -1932735284
.long 16383
Подробнее здесь: https://stackoverflow.com/questions/792 ... ent-with-f
Почему gcc сравнивает, казалось бы, равные значения с плавающей запятой как разные с «-fexcess-precision=standard»? ⇐ C++
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение