Изменение режима округления с плавающей запятой
Каков наиболее эффективный способ изменения режима округления * чисел с плавающей запятой IEEE 754? Портативная функция C будет приятной, но решение, использующее сборку x86, тоже в порядке.
* Я имею в виду стандартные режимы округления к ближайшему, к нулю и к положительной / отрицательной бесконечности
- Как представить 0,1 в арифметике с плавающей точкой и десятичной запятой
- Проверка, является ли float целым числом
- Печать двойная без потери точности
- Плавающая точка и целочисленные вычисления на современном оборудовании
- Как проверить, использует ли C ++-компилятор стандарт IEEE 754 с плавающей запятой
- Почему преобразование из float в double изменяет значение?
- разбиение числа на целые и десятичные числа
- Проблема с поплавками в Objective-C
- Самый быстрый способ сделать горизонтальную векторную сумму float на x86
- Спецификатор ширины печати для поддержания точности значения с плавающей запятой
- Оптимизация для быстрого умножения, но медленное добавление: FMA и doubleedouble
- Драйвер Microsoft ACE изменяет точность с плавающей запятой в остальной части моей программы
- Какие операции и функции на +0.0 и -0.0 дают разные арифметические результаты?
Это стандартное решение C:
#include #pragma STDC FENV_ACCESS ON // store the original rounding mode const int originalRounding = fegetround( ); // establish the desired rounding mode fesetround(FE_TOWARDZERO); // do whatever you need to do ... // ... and restore the original mode afterwards fesetround(originalRounding);
На задних платформах, где отсутствует поддержка C99, вам, возможно, придется прибегать к сборке. В этом случае вы можете установить округление для блока x87 (через команду fldcw
) и SSE (через инструкцию ldmxcsr
).
Редактировать Вам не нужно прибегать к сборке для MSVC. Вместо этого вы можете использовать (полностью нестандартный) _control_fp( )
:
unsigned int originalRounding = _control_fp(0, 0); _control_fp(_RC_CHOP, _MCW_RC); // do something ... _control_fp(originalRounding, _MCW_RC);
Вы можете больше узнать о _control_fp () в MSDN .
И, просто для полноты, кольцо декодера для имен макросов для режимов округления:
rounding mode C name MSVC name ----------------------------------------- to nearest FE_TONEAREST _RC_NEAR toward zero FE_TOWARDZERO _RC_CHOP to +infinity FE_UPWARD _RC_UP to -infinity FE_DOWNWARD _RC_DOWN
это может помочь.
Изменить: я бы сказал, что вам нужна ваша собственная функция. Вы можете использовать сборку внутри C.
Но если вы зарегистрируете размер 64 бит, округлите его до 32 бит, сделайте ваши вычисления быстрее. Это на самом деле сделает его медленнее. Помните, что 64-битные вычисления просты для 64-х микропроцессоров, а не 2-32 бит. Я не знаю, чего именно вы хотите достичь. Я знаю, что производительность зависит от ваших критериев.