Делает любой имеет удобный отрывки кода для преобразования IEEE 754 double
к сразу нижнему (resp. выше) float
, не изменяясь или принимая что-нибудь о текущем режиме округления FPU?
Примечание: это ограничение, вероятно, подразумевает не использование FPU вообще. Я ожидаю, что самый простой способ сделать это в этих условиях состоит в том, чтобы считать биты двойного в 64-разрядном длинном и работать с этим.
Можно принять порядок байтов по Вашему выбору для простоты, и что двойное рассматриваемое доступно через d
поле объединения ниже:
union double_bits
{
long i;
double d;
};
Я попытался бы сделать это сам, но я уверен, что представил бы трудные к уведомлению ошибки для денормализованных или отрицательных чисел.
думаю, что это сработает, но сначала я сформулирую свои предположения:
nextafterf()
(он указан в C99).Также, скорее всего, этот метод не очень эффективен.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[])
{
/* Change to non-zero for superior, otherwise inferior */
int superior = 0;
/* double value to convert */
double d = 0.1;
float f;
double tmp = d;
if (argc > 1)
d = strtod(argv[1], NULL);
/* First, get an approximation of the double value */
f = d;
/* Now, convert that back to double */
tmp = f;
/* Print the numbers. %a is C99 */
printf("Double: %.20f (%a)\n", d, d);
printf("Float: %.20f (%a)\n", f, f);
printf("tmp: %.20f (%a)\n", tmp, tmp);
if (superior) {
/* If we wanted superior, and got a smaller value,
get the next value */
if (tmp < d)
f = nextafterf(f, INFINITY);
} else {
if (tmp > d)
f = nextafterf(f, -INFINITY);
}
printf("converted: %.20f (%a)\n", f, f);
return 0;
}
На моем компьютере он печатает:
Double: 0.10000000000000000555 (0x1.999999999999ap-4)
Float: 0.10000000149011611938 (0x1.99999ap-4)
tmp: 0.10000000149011611938 (0x1.99999ap-4)
converted: 0.09999999403953552246 (0x1.999998p-4)
Идея заключается в том, что я преобразую значение double
в float
- оно может быть меньше или больше двойного значения в зависимости от режима округления. При преобразовании обратно в double
мы можем проверить, меньше или больше ли оно исходного значения. Затем, если значение float
не в правильном направлении, мы посмотрим на следующее float
число из преобразованного числа в направлении исходного числа.
Чтобы сделать эту работу точнее, чем просто перекомбинировать мантиссу и бит экспонента, проверьте:
http://www.mathworks.com/matlabcentral/fileexchange/23173
regards
.