浮点类型详解

目录

前言

基础知识

十进制浮点数与二进制浮点数的转换

十六进制数浮点数

浮点数的存储

浮点数存储的格式

规范化

舍入处理

溢出操作

浮点数的计算 


 注:所有的[斜体]内容都是本人自己杜撰的概念,只代表个人理解,可能不能与科学规范的学术概念相吻合

             所有的{   }包含的是一个格式

             所有的"   "包含的是一个对象实体

前言

从一个简单的程序里发现了点蹊跷

float a = 2.0e20+1.0;
float b = a - 2.0e20;
printf("%a",b);
┌──(ivaldi㉿kali)-[~/Desktop/C/float]
└─$ cd "/home/ivaldi/Desktop/C/float/" && gcc main.c -o main && "/home/ivaldi/Desktop/C/float/"main
0x1.d29cfp+41

基础知识

十进制浮点数与二进制浮点数的转换

首先抛开计算机存储的限制,我们来看看如何把一个[十进制浮点数]转化为一个[二进制浮点数]:

0.分离[十进制浮点数]为[符号位]和[不带符号位的十进制浮点数],这个[符号位]与[二进制浮点数]中所包含的[符号位]相同

1.分离[不带符号位的十进制浮点数]为[不带符号位的十进制浮点数的整数部分]和[不带符号位的十进制浮点数的小数部分]

2.[不带符号位的十进制数的整数部分]采用"除以2取余数,倒序相加"的方法,转化为[不带符号位的二进制数的整数部分]

3.[不带符号位的十进制数的小数部分]采用"乘以2取整数,顺序相加"的方法,转化为[不带符号位的二进制数的小数部分]

4.按照{[符号位]+[不带符号位的二进制数的整数部分]+[小数点] "."+[不带符号位的二进制数的小数部分]}的格式拼接在一起就变成了[二进制浮点数]

下面是一个简单的例子:

[十进制浮点数] "-4.8125" 转化为 [二进制浮点数]

(0)[十进制浮点数] "-4.8125" 分成 [符号位] "-" 和 [不带符号位的十进制浮点数] "4.8125"

(1)[不带符号位的十进制浮点数] "4.8125" 分成 [不带符号位的十进制浮点数的整数部分] "4和[不带符号位的十进制浮点数的小数部分] "0.8125"

(2)[不带符号位的十进制浮点数的整数部分] "4" 转化为[不带符号位的二进制数的整数部分] "100"

        4 除以 2 = 2 ...... 0

                         2 除以 2 = 1......0

                                          1 除以 2 = 0......1       

        得到商为0就没必要继续除了,如果继续除,得到的商和余数都是0,就进入无限循环了

        把依次得到的余数,按照倒序,连接在一起,变成"100",这就是[不带符号位的二进制数的整数部分]的结果

(3)[不带符号位的十进制浮点数的小数部分] "0.8125" 转化为[不带符号位的二进制数的小数部分] "1101"

        0.8125 乘以 2 = 0.625 + 1

                                  0.625 乘以 2 = 0.25 + 1

                                                          0.25 乘以 2 = 0.5 + 0

                                                                                0.5 乘以 2 = 0.0 + 1

        得到小数部分为0就没必要继续乘了,如果继续乘,得到的积都是0,就进入无限循环了

        把依次得到的整数部分,按照顺序,连接在一起,变成"1101",这就是[不带符号位的二进制数的小数部分]的结果

(4)按照{[符号位] "-" +[不带符号位的二进制数的整数部分] "100"+[小数点] "."+[不带符号位的二进制数的小数部分] "1101"}的格式,拼接在一起,就变成了[二进制浮点数]"-100.1101",当然,这也可以表示为"-1.001101*2^2"

十六进制数浮点数

[十六进制数浮点数]是[二进制浮点数]的另一种表达形式,差别在于:

  • ANSI-C中支持[十进制浮点数]格式的浮点型常量的书写,但是不支持[二进制浮点数]格式的浮点型常量的书写
  • [二进制浮点数]只是计算机硬件层面的一种表现方式和原理体现
  • C99标准中新增加了对[十六进制数浮点数]格式的浮点型常量的书写的支持
  • [十六进制数浮点数]本质还是[二进制浮点数],只是[二进制浮点数]的另一种表达形式

将一个[二进制浮点数]转化为[十六进制数浮点数]的步骤:

0.将[二进制浮点数]拆解成[符号位]+[不带符号位的二进制浮点数]

1.将[不带符号位的二进制浮点数]拆解成[不带符号位的二进制浮点数的整数部分]+[小数点]+[不带符号位的二进制浮点数的小数部分]

2.[不带符号位的二进制浮点数的整数部分]从右往左,每4个一组,不足补0,转化为十六进制数,变成[不带符号位的十六进制数浮点数的整数部分]

3.[不带符号位的二进制浮点数的小数部分]从左往右,每4个一组,不足补0,转化为十六进制数,变成[不带符号位的十六进制数浮点数的小数部分]

4.按照{[十六进制前缀]+[符号位] +[不带符号位的十六进制数浮点数的整数部分]+[小数点]+[不带符号位的十六进制数浮点数的小数部分]}的格式,合成[十六进制数浮点数]

还是上面那个简单的例子:

"-100.1101"  ->  "-"+"100"+"."+"1101"  ->  "-"+"0100"+"."+"

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值