浮点数的存储方式,取值范围和舍入模式

浮点数的存储方式

IEEE754提供了二进制存储十进制浮点数的具体标准,分别为单精度型,双精度型,延伸单精度型,延伸双精度型。

一 单精度类型(float)

符号位S:31位,0代表正,1代表负

指数位E:23-30位

尾数位F:0-22位

一个十进制浮点数可以表示为: 

规范化

尾数的小数点放在第一位和第二位之间,且保证第一位不为0,故尾数始终表示为1.****,这个处理过程称为规范化(normailzed)

规范化之后,尾数始终表示为1.****,存储尾数时,省略前面的1,只记录小数点之后的部分,不够23位的在低位补0。

IEEE754规定,单精度浮点数的指数位用于表示[-127, 128]范围内的指数(双精度的偏移量为1023),浮点型的指数位都有一个固定的偏移量(bias),指数 + 偏移量 = 非负整数。因此实际计算需要减去这个偏移量B。

现在一个十进制数可以表示为:

规格数和非规格数

根据IEEE754的规定, 按照尾数位隐藏的整数部分是 1. 还是0. 可以将浮点数划分为两类: normal number(规格数) 和 subnormal number(非规格数)

尾数位隐藏的整数部分为1.的数称为规格数,大部分数都为规格数,存储尾数时,省略前面的1,只存储小数点之后的部分;

尾数位隐藏的整数部分为0.的数称为非规格数,为了表示subnormal number, IEEE754规定: 如果将指数位全部填充为0, 则表示这个数是个非规格数。

特殊数

特殊数分为两种: 无穷(infinity)和NaN(not a number)

无穷

当指数位全为1,且尾数位全为0时,就表示为无穷,根据符号位来确定是正无穷还是负无穷,分别记做+infinity和-infinity,由于浮点数有其取值范围,超过范围就被记作无穷,关于浮点数的取值范围下面再说。

NAN

当指数位全为1,且尾数位不全为0,就表示为NaN,NaN没有+/-之分,统称NaN。

二 双精度类型(double float)

存储双精度浮点数需要64个比特位,其中最高位仍是符号位S,而指数位E提升到了11位,尾数位F提升到了52位。

这里有个可以方便实现十进制数到32位浮点数转换的网站网站https://www.h-schmidt.net/FloatConverter/IEEE754.html可惜该网站暂时不能计算双精度64位,不过借助ChatGPT可以方便的写一段代码帮助查看,借助菜鸟的c在线编译网站可以运行查看。

#include <stdio.h>

// 联合体用于类型转换
typedef union {
    double num;
    unsigned long long bits;
} DoubleBits;

void printBinary(double num) {
    DoubleBits converter;
    converter.num = num;

    // 从最高位到最低位逐位输出
    for (int i = (sizeof(converter.bits) * 8) - 1; i >= 0; --i) {
        unsigned long long mask = 1ULL << i;  // 构造掩码

        // 使用掩码进行与运算判断该位是0还是1
        int bit = (converter.bits & mask) ? 1 : 0;

        printf("%d", bit);

        if (i % 8 == 0) {
            printf(" ");  // 每8位添加一个空格
        }
    }

    printf("\n");
}

int main() {
    double num = 1.111; // input your number

    printf("二进制表示为:");
    printBinary(num);

    return 0;
}

浮点数所表示的范围

wiki给出的取值范围:

计算方式

如上所述,IEEE754规定,当指数位全部为0或者全部为1时,用于表示两种特殊状态的数: subnormal number 和 non-number,所以现在可以得到如下示意图, 以32位单精度浮点数为例:

对于指数,由于指数部分无法取到全0或者全1,减去偏置(127)之后,取值范围为[-126,127]。

对于尾数,规范数尾数前时钟隐藏整数位1,因此尾数的取值范围其实是[1.000...,1.111...],约等于十进制的[1,2),左闭右开。

在有了指数和尾数的取值范围之后,整个浮点的取值范围也就随之确定了,根据运算规则,32为浮点的取值范围为: ±[1,2) × 2^[-126,127] = (-2 × 2^127,-1 × 2^-126] ∪ [1 × 2^-126,2 × 2^127)

转换成以10为底之后:

取一个更容易表示的子集,就是我们常见的32位float的取值范围:

四种舍入模式

一 就近舍入

十进制的四舍五入,大于0.5即进位1,小于0.5则舍掉。

二 朝0舍入

朝零舍入即朝数轴零点方向舍入,直接截位即可。

三 朝正无穷舍入

对于正数,多余位为0则直接截位,不全为0则进1;

对于负数,无论多余位是多少直接截位;

四 朝负无穷舍入

对于负数,多余位为0则直接截位,不全为0则进1;

对于正数,无论多余位是多少直接截位;

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值