我想计算float和double中的尾数位数。 我知道这些数字应该是23和52,但我必须在我的程序中计算它。
答案 0 :(得分:5)
您可以使用标题<cfloat>
例如,请参阅FLT_MANT_DIG。
答案 1 :(得分:3)
尾数位数存在歧义:它可能是
通常,以IEEE浮点格式存储的尾数不包括对所有常规非零数字暗示的初始1
。因此,表示中的位数比真正的位数少一个。
您可以通过不同方式为二进制浮点格式计算此数字:
FLT_MANT_BITS
,DBL_MANT_BITS
和LDBL_MANT_BITS
。该值是尾数位的真实数。FLT_EPSILON
中定义的<float.h>
的直接计算中导出位数:FLT_EPSILON
是最小的浮点值,使1.0f + FLT_EPSILON
与{1.0f
不同1}}。真尾数是1 - log(FLT_EPSILON) / log(2)
。相同的公式可用于其他浮点格式。这是一个测试工具:
#include <float.h>
#include <math.h>
#include <stdio.h>
int main(void) {
int n;
float f = 1.0;
for (n = 0; 1.0f + f != 1.0f; n++) {
f /= 2;
}
#ifdef FLT_MANT_BITS
printf("#define FLT_MANT_BITS %d\n", FLT_MANT_BITS);
#endif
#ifdef FLT_EPSILON
printf("1 - log(FLT_EPSILON)/log(2) = %g\n", 1 - log(FLT_EPSILON) / log(2));
#endif
printf("Mantissa bits for float: %d\n", n);
double d = 1.0;
for (n = 0; 1.0 + d != 1.0; n++) {
d /= 2;
}
#ifdef DBL_MANT_BITS
printf("#define DBL_MANT_BITS %d\n", DBL_MANT_BITS);
#endif
#ifdef DBL_EPSILON
printf("1 - log(DBL_EPSILON)/log(2) = %g\n", 1 - log(DBL_EPSILON) / log(2));
#endif
printf("Mantissa bits for double: %d\n", n);
long double ld = 1.0;
for (n = 0; 1.0 + ld != 1.0; n++) {
ld /= 2;
}
#ifdef LDBL_MANT_BITS
printf("#define LDBL_MANT_BITS %d\n", LDBL_MANT_BITS);
#endif
#ifdef LDBL_EPSILON
printf("1 - log(LDBL_EPSILON)/log(2) = %g\n", 1 - log(LDBL_EPSILON) / log(2));
#endif
printf("Mantissa bits for long double: %d\n", n);
return 0;
}
我的笔记本电脑输出:
1 - log(FLT_EPSILON)/log(2) = 24
Mantissa bits for float: 24
1 - log(DBL_EPSILON)/log(2) = 53
Mantissa bits for double: 53
1 - log(LDBL_EPSILON)/log(2) = 64
Mantissa bits for long double: 64