文章目录
在做 MPI 大数据排序实验的时候,因为要求自己实现生成随机排序的浮点数数据,所以写了一个简单的 C 生成随机数。没怎么多想就按照整型随机数数据集的生成方式来了,就是先生成一个 [ 0.0 , 1.0 ] [0.0, 1.0] [0.0,1.0] 之间的小数,然后乘以
float
类型所能表示的最大值来生成可能的浮点数范围内的任意值。但是当我检查生成的二进制数据文件读取浮点数时,发现浮点数的整型部分都非常大,并且小数部分都为零,百思不得其解。
float gen_random_flt()
{
// 生成一个在 [0, 1] 范围内的随机浮点数
float scale = (float)rand() / (float)RAND_MAX;
// 随机决定是正数还是负数
float sign = (rand() % 2 ? 1.0f : -1.0f); // 生成 -1 或 1
// 将随机浮点数映射到 [-FLT_MAX, FLT_MAX] 范围
return sign * scale * FLT_MAX + scale;
// return sign * scale;
}
我还特意在返回浮点数的时候,加一个 [ 0.0 , 1.0 ] [0.0, 1.0] [0.0,1.0] 范围之间的小数,这样总能保证小数部分不是全为零了吧。结果输出一看,还是全部都是零:
312074220398877433439531912707967025152.000000
float
类型的浮点数,十进制小数点输出是 6 位,然后 double
类型的话可以去到 16 位十进制小数。但是为什么小数部分没有显示呢?如果单生成 [ 0.0 , 1.0 ] [0.0, 1.0] [0.0,1.0] 部分的小数的话,打印二进制文件里面的浮点数数据又是可以显示的:
-0.157101 0.983587 -0.751909 -0.583410 0.082617 0.445290 -0.836798 -0.527569 -0.666163 0.714496 0.434055 0.626577 0.449175 -0.802974 -0.672282 -0.494159 0.969527 -0.614576 0.772751 0.874313 -0.062900 0.690523 -0.498628 -0.344090 -0.262711 0.267150 ...
所以我猜测应该是和浮点数所能表示的最大大小有关系。那么 FLT_MAX
宏定义定义的数值是多少呢?
#define FLT_MAX __FLT_MAX__
扩展到:
3.40282346638528859811704183484516925e+38F
使用了十进制的 38 次方,这个数确实有点大了,所以我去谷歌了一下看看别人有没有遇到这个情况,基本上是说浮点数正确的比较方法,以及为什么会导致精度丢失的问题,都不是我这个不显示小数部分的问题。
直到这篇