История изменений
Исправление PRN, (текущая версия) :
Я имею в виду модели округления описанные в самом стандарте.
В https://gcc.gnu.org/wiki/FloatingPointMath есть интересные комментарии в секции Transformations
:
0.0 - 0.0 = +0.0, not -0.0, unless rounding to -Inf
0.0 - 0.0 = -0.0, when rounding to -Inf
Т.е. если округление в сторону -Inf
, то будет отрицательный ноль.
«Фикс» анона с хаком установки модели округления:
#include <stdio.h>
#include <xmmintrin.h>
void set_round_down() {
const unsigned int down = _MM_MASK_MASK | _MM_ROUND_DOWN;
asm (
"ldmxcsr %0" : : "m" (down)
);
}
int main() {
volatile float right = -2.0, left = 2.0, zero = 0;
float res = (right + left) / (right - left);
printf("%5.12e\n", res);
set_round_down();
res = res + zero;
printf("%5.12e\n", res);
return 0;
}
gcc -O1 -ffast-math main.cpp
./a.out
-0.000000000000e+00
-0.000000000000e+00
Не работает LMAO)
Исходная версия PRN, :
Я имею в виду модели округления описанные в самом стандарте.
В https://gcc.gnu.org/wiki/FloatingPointMath есть интересное комментарии в секции Transformations
:
0.0 - 0.0 = +0.0, not -0.0, unless rounding to -Inf
0.0 - 0.0 = -0.0, when rounding to -Inf
Т.е. если округление в сторону -Inf
, то будет отрицательный ноль.
«Фикс» анона с хаком установки модели округления:
#include <stdio.h>
#include <xmmintrin.h>
void set_round_down() {
const unsigned int down = _MM_MASK_MASK | _MM_ROUND_DOWN;
asm (
"ldmxcsr %0" : : "m" (down)
);
}
int main() {
volatile float right = -2.0, left = 2.0, zero = 0;
float res = (right + left) / (right - left);
printf("%5.12e\n", res);
set_round_down();
res = res + zero;
printf("%5.12e\n", res);
return 0;
}
gcc -O1 -ffast-math main.cpp
./a.out
-0.000000000000e+00
-0.000000000000e+00
Не работает LMAO)