Самым простым способом проверки различной точности x87 может быть использование long double
, что для целей x86 является 80-битным типом x87. (За исключением Windows, где long double = double).
Другое преимущество long double
состоит в том, что вам не нужно компилировать с -m32
, чтобы вообще использовать x87. (По умолчанию для -m64
установлено значение -mfpmath=sse
; двойная математика и вычисление с плавающей запятой будут выполняться в регистрах XMM с шириной шрифта, не расширенной до внутренней точности x87. Но long double
всегда будет использовать x87, поскольку SSE / SSE2 не может сделать 80 бит). TL: DR: в обычном 64-битном системном сборке с gcc -mpc32 foo.c
, -mpc32
не будет иметь никакого значения для математики по double
переменным, потому что он даже не использует устаревший x87 FPU.
Кстати, этот тестовый пример также зависит от компиляции со значением по умолчанию -O0
, иначе произойдет постоянное распространение во время компиляции. (И это вряд ли будет уважать -mpc32
.)
137.142364501953125f
- это константа float
, округленная до значения с плавающей точкой, перед использованием в качестве инициализатора для double
. Таким образом, все ваши начальные значения округлены до ближайшего float
, несмотря на то, что хранятся как double
. Я предполагаю, что деление не точное, поэтому вы все равно получите округление.
Я предполагаю, что эти параметры просто устанавливают точность x87 при запуске. Код запуска MST C CRT, очевидно, делает то же самое, по умолчанию устанавливая 64-битную точность (53-битная мантисса, как double
, не полная точность). См. Статью Брюса Доусона Intermediate Float-Precision ; одна из серии статей о ФП. Индекс в этом .
Вы можете посмотреть на asm, генерируемый компилятором, чтобы увидеть, как он выполняет FP математику: использование fld
/ fmul
/ fstp
равно x87 и будет зависит от точности x87, установленной в регистре управляющих слов x87.
movsd
/ mulsd
- это SSE2, а точность задается инструкцией; никакие биты состояния / управления не могут переопределить его. (В MXCSR можно изменить только режим округления и обработку субнормалей.)