Результат операции округления в меньшую сторону в IEEE 754 - PullRequest
1 голос
/ 07 мая 2020

Для операций, использующих значения одинарной точности в IEEE 754 (float, 32bit), есть ли способ каким-либо образом обусловить два операнда, чтобы гарантировать, что результат операции округляется в меньшую сторону, когда точный результат невозможен? Другими словами, как я могу принудительно округлить до -Inf?

Пример:

  • Типичный результат (с использованием 'округления до ближайшего'): 1.0f / 3.0f = 0.3333333432674407958984375f
  • Ожидаемый результат (с использованием «округления вниз»): 1.0f / 3.0f = 0.333333313465118408203125f

В качестве дополнительной информации я бы сделал это на C99, и (к сожалению) настроить FPU невозможно.

1 Ответ

2 голосов
/ 07 мая 2020

И C 1999, и текущий C стандарт определяют средства для установки режима округления с плавающей запятой. Однако не все реализации C их поддерживают. В реализациях, которые это делают, следующий код сохранит предыдущий режим округления, выполнит операции с округлением до отрицательной бесконечности и восстановит предыдущий режим округления:

//  Declare identifiers for accessing floating-point environment.
#include <fenv.h>


void foo(void *data)
{
    //  Inform compiler this code accesses the floating-point environment.
    #pragma STDC FENV_ACCESS ON

    //  Save caller's rounding mode.
    int PreviousRoundingMode = fegetround();

    //  Set desired rounding mode.
    if (fesetround(FE_DOWNWARD) != 0)
    {
        //  fesetround failed.  Handle error.
    }

    //  Insert here code to perform desired operations.

    //  Restore previous rounding mode.
    fesetround(PreviousRoundingMode);
}
}

Обратите внимание, что basi c operations, можно ожидать, что такие как +, *, -, / и fma будут соответствовать режиму округления, но функции математической библиотеки, такие как sin или log, могут не соответствовать.

...