LINUX.ORG.RU

История изменений

Исправление 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)