Преобразование длинных двойных в двойные с округлением вверх (или вниз)

Предположим, что мы работаем на платформе, где тип long double имеет строго большую точность, чем 64 бита. Какой самый быстрый способ конвертировать данный long double к обычному числу двойной точности с некоторым заданным округлением (вверх, вниз, округление до ближайшего и т. д.)?

Для уточнения вопроса приведу конкретный пример: N быть данным long double, а также M быть double чье значение минимизирует (реальное) значение M - N такой, что M > N, это M было бы округленное вверх преобразование, которое я хочу найти.

Могу ли я обойтись без правильной настройки режима округления среды FP и выполнения простого приведения (например, (double) N)?

Пояснение: Вы можете предположить, что платформа поддерживает стандарт IEEE для арифметики с плавающей точкой (IEEE 754).

1 ответ

Решение

Могу ли я обойтись без правильной настройки режима округления среды FP и выполнения простого приведения (например, (double) N)?

Да, до тех пор, пока компилятор реализует IEEE 754 (большинство из них делают хотя бы приблизительно). Преобразование из одного формата с плавающей запятой в другой является одной из операций, к которой, согласно IEEE 754, должен применяться режим округления. Чтобы конвертировать из long double в double вверх, установите режим округления вверх и выполните преобразование.

В C99, который должен приниматься компиляторами C++ (я не уверен, что для C++ указан синтаксис):

#include <fenv.h>
#pragma STDC FENV_ACCESS ON
…
fesetround(FE_UPWARD);
double d = (double) ld;

PS: вы можете обнаружить, что ваш компилятор не реализует #pragma STDC FENV_ACCESS ON должным образом. Добро пожаловать в клуб.

Другие вопросы по тегам