В MSVC режим с плавающей точкой по умолчанию - precise (/fp:precise)
. Это означает, что оптимизатор может выполнять определенные оптимизации для повышения точности или производительности.
Попробуйте изменить режим на strict (/fp:strict)
. Это заставит компилятор следовать строгим правилам с плавающей точкой при округлении и тому подобное.
(РЕДАКТИРОВАТЬ: strict (/fp:strict)
, похоже, не работает в этом случае ...)
Если вы посмотрите на разборку оптимизированной сборки, вы увидите, что все вычисления были свернуты и оптимизированы.
push 5374 ; 000014feH
push 5374 ; 000014feH
push OFFSET ??_C@_07MHMABKGB@?$CFd?0?5?$CFd?6?$AA@
call DWORD PTR __imp__printf
add esp, 12 ; 0000000cH
РЕДАКТИРОВАТЬ: Это похоже на ошибку оптимизатора компилятора.
При strict (/fp:strict)
следующий код дает разные результаты:
float a = 411.00418f;
float b = 1.0f;
float c = 0.076279849f;
unsigned short result1 = (unsigned short)((float)((a-b)/c));
float d = (float)((a-b)/c);
unsigned short result2 = (unsigned short)( d );
Выход:
5374, 5375
Извлечение (float)((a-b)/c)
в отдельное назначение не должно влиять на результаты в strict (/fp:strict)
.
Я знаю одного из ребят, которые работают над оптимизатором MSVC. Я пришлю ему сообщение об ошибке.
Обновление:
Вот их ответ:
Привет, Алекс, спасибо за этот отчет об ошибке. Я постараюсь исправить это для
готовящийся к выпуску выпуск VC ++, но он может этого не сделать.
FWIW, ошибка не воспроизводится, если вы выбрасываете / arch: SSE2, и поскольку мы
по умолчанию включают / arch: SSE2 для следующего выпуска VC ++
(https://connect.microsoft.com/VisualStudio/feedback/details/688736/compiler-generates-sse-instructions-without-arch-sse).
Итак, поведение по умолчанию покажет, что эта ошибка исправлена. Но если
Вы вернетесь к старой модели FP (throw / arch: IA32), ошибка может
все еще присутствовать.
Эрик
Итак, они подтвердили это как ошибку.