私は次のように動作すると思いますが、最初に私の仮定を述べます。
- 浮動小数点数は、実装で IEEE-754 形式で格納されます。
- オーバーフローなし、
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 値よりも小さい場合も大きい場合もあります。に戻すとdouble
、元の値より小さいか大きいかを確認できます。次に、 の値がfloat
正しい方向にない場合はfloat
、変換された数値から元の数値の方向に次の数値を調べます。