Creo que las siguientes obras, pero voy a exponer mis suposiciones primera :
- números de coma flotante se almacenan en formato IEEE-754 en su aplicación,
- Sin desbordamiento,
- Tiene
nextafterf()
disponible (está especificado en C99).
Además, lo más probable es que este método no sea muy eficiente.
#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;
}
En mi máquina, imprime:
Double: 0.10000000000000000555 (0x1.999999999999ap-4)
Float: 0.10000000149011611938 (0x1.99999ap-4)
tmp: 0.10000000149011611938 (0x1.99999ap-4)
converted: 0.09999999403953552246 (0x1.999998p-4)
La idea es que estoy convirtiendo el valor double
a un valor float
— esto podría ser menor o mayor que el valor doble dependiendo de la modo de redondeo. Cuando se convierte de nuevo a double
, podemos verificar si es menor o mayor que el valor original. Entonces, si el valor de float
no está en la dirección correcta, nos fijamos en el siguiente número float
del número convertido en la dirección del número original.
en sistemas glibc a encontrar un ieee754.h archivo de cabecera, que define las uniones de los tipos de coma flotante y una estructura de campo de bits, para que pueda trabajar con la mantisa y el exponente más fácil, lo siento pero no se puede dar verdadera código. – quinmars