Почему gcc сравнивает, казалось бы, равные значения с плавающей запятой как разные с «-fexcess-precision=standard»?C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Почему gcc сравнивает, казалось бы, равные значения с плавающей запятой как разные с «-fexcess-precision=standard»?

Сообщение Anonymous »

Посмотрите на этот фрагмент:
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
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»