从 IEEE 754 浮点数表示法解释浮点数运算损失小数部分的问题


在做 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 次方,这个数确实有点大了,所以我去谷歌了一下看看别人有没有遇到这个情况,基本上是说浮点数正确的比较方法,以及为什么会导致精度丢失的问题,都不是我这个不显示小数部分的问题。

直到这篇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值