豫ICP备17040950号-2

浮点数怎么用二进制表示

文章目录

对于浮点数在计算机中是怎么用二进制表示的,这个知识点让我学了很久,很多资料讲的特别抽象难懂,所以今天我想用自己的方式讲一讲。
学过 《计算机组成原理》 或者类似 《计算机系统》 这些课程的小伙伴们应该都知道,浮点数在计算机中的存储方式遵循IEEE 754 浮点数计数标准,

IEEE二进制浮点数算术标准(IEEE 754) 是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用。这个标准定义了表示浮点数的格式(包括负零-0)与反常值(denormal number),一些特殊数值((无穷(Inf)与非数值(NaN)),以及这些数值的“浮点数运算符”;它也指明了四种数值舍入规则和五种例外状况(包括例外发生的时机与处理方式)。

IEEE 754规定了四种表示浮点数值的方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80位实现)。只有32位模式有强制要求,其他都是选择性的。大部分编程语言都提供了IEEE浮点数格式与算术,但有些将其列为非必需的。例如,IEEE 754问世之前就有的C语言,现在包括了IEEE算术,但不算作强制要求(C语言的float通常是指IEEE单精确度,而double是指双精确度)。

该标准的全称为IEEE二进制浮点数算术标准(ANSI/IEEE Std 754-1985),又称IEC 60559:1989,微处理器系统的二进制浮点数算术(本来的编号是IEC 559:1989)[1]。后来还有“与基数无关的浮点数”的“IEEE 854-1987标准”,有规定基数为2跟10的状况。现在最新标准是“ISO/IEC/IEEE FDIS 60559:2010”。

在六、七十年代,各家计算机公司的各个型号的计算机,有着千差万别的浮点数表示,却没有一个业界通用的标准。这给数据交换、计算机协同工作造成了极大不便。IEEE的浮点数专业小组于七十年代末期开始酝酿浮点数的标准。在1980年,英特尔公司就推出了单片的8087浮点数协处理器,其浮点数表示法及定义的运算具有足够的合理性、先进性,被IEEE采用作为浮点数的标准,于1985年发布。而在此前,这一标准的内容已在八十年代初期被各计算机公司广泛采用,成了事实上的业界工业标准。加州大学伯克利分校的数值计算与计算机科学教授威廉·卡韩被誉为“浮点数之父”。

IEEE 754 浮点数可以表示为:

image.png

图片采用尾数 + 阶码的编码方式,更通俗一点说,就是类似于数学课本上所学的科学计数法表示方式:有效数字 + 指数位!
因此,只要给出:符号(S)阶码部分(E)尾数部分(M) 这三个维度的信息,一个浮点数的表示就完全确定下来了,所以float和double这两种类型的浮点数在计算机中的存储结构如下:

image.png
image.png

1、符号部分(S)

0-正

1-负

2、阶码部分(E)(指数部分)

对于float型浮点数,指数部分8位,考虑可正可负,因此可以表示的指数范围为-127 ~ 128
对于double型浮点数,指数部分11位,考虑可正可负,因此可以表示的指数范围为-1023 ~ 1024

3、尾数部分(M)

浮点数的精度就是由尾数部分决定的

对于float型浮点数,尾数部分23位,换算成十进制就是 2^23=8388608,所以十进制精度只有6 ~ 7位
对于double型浮点数,尾数部分52位,换算成十进制就是 2^52 = 4503599627370496,所以十进制精度只有15 ~ 16位
所以,浮点数交给计算机存储的时候,可能会有精度丢失问题!!!因此使用时需要格外小心,如果真因为这一块出了bug,定位问题还是非常艰难的,所以预防工作要做好。

我们先来举个例子详细说明一下浮点数怎么转换成二进制数

比如:把十进制小数0.875转换成二进制,具体怎么操作?
可以分几大步走:
第一:以小数为界限划分成整数部分小数部分
第二:我们开始来整数部分的转换,这里的整数是为十进制数,转换成二进制数的方式是除以二取余数,这里的整数部分为零,那转换成二进制数也为零。
第三:小数部分的转换,小数部分的转换的方式是乘二取整数,如下图

image.png

第四:将结果合并,就可以得到这个结果为0.111

所以该结果按照上一节所述的尾数 + 阶码的计算机计数方式,则可以表示为:

image.png

符号位0
阶码(E)部分:若以float为例,应为 127 +(-1)= 126,因此二进制表示为:01111110
尾数部分(M):若以float为例,应为23位,因此尾部补齐后为11000000000000000000000

因此最终的总结果为(以32位精度float表示):

1
00111111011000000000000000000000

C语言打印浮点数的二进制表示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
#include <stdlib.h>
/*
num是要展示的float数,bin是保存所有二进制位的数组
*/
void getFloatBin(float num,char bin[])
{
int t = 1;//用来按位与操作
int *f = (int*)(&num);//将float的解释成int,即float的地址转成int*
for(int i=0;i<32;i++)
{
//从最高位开始按位与,如果为1,则bin[i]=1,如果为0,则bin[i]=0
//这里没有将bin存成字符,而是数字1 0
bin[i] = (*f)&(t<<31-i)?1:0;
}
}
int main()
{
float test = 100;
char c[32];
printf("测试float数为:%f\n",test);
printf("二进制表示为:");
getFloatBin(test,c);
for(int i=0;i<32;i++)
{
printf("%d",c[i]);
if(i==0)
printf(", ");
if(i==8)
printf(", ");
}
}

注:我们一般用的x86是小端模式,就是高地址放数据的高位部分,详情可查阅资料。

以下为几个浮点数二进制存储表示:

​ 注意:形如2^[3]表示2的3次方

实例一38414.4 的IEEE浮点数表示法(double):

double型的指数域有11位,所以偏置值为 2^[11-1]-1 = 1023
38414.4 = 1001011000001110. 0110011001100110011001100110011001101 = 1. 00101100000111001100110011001100110011001100110011012[15]
//0.4=0.5
0+0.251+0.1251+0.0625*0+……没完没了,但小数域只需52位,整数部分已经有了15位,故小数部分只需取37位.
指数域 = (15+1023)B = 1000 0001 110
小数域 = 0010 1100 0001 1100 1100 1100 1100 1100 1100 1100 1100 1100 1101
最终表示:
0 1000 0001 110 0010 1100 0001 1100 1100 1100 1100 1100 1100 1100 1100 1100 1101
符号 指数域 (11) 小数域(52)
格式化为:
01000000 11100010 11000001 11001100 11001100 11001100 11001100 11001101

实例二234.5 的IEEE浮点数表示法(double):

double型的指数域有11位,所以偏置值为 2^[11-1]-1 = 1023
234.5 = 11101010.1 = (1. 11010101)*2[7]
指数域 = (7+1023)B = 1000 0000 110
小数域 = 1101 0101 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
//小数域需要52位,但11010101只有8位,不足就后面补0.
最终表示:
0 1000 0000 110 1101 0101 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
符号 指数域(11) 小数域(52)
格式化为:
01000000 01101101 01010000 00000000 00000000 00000000 00000000 00000000

实例三3490593.0 的IEEE浮点数表示法(float):

float型的指数域有8位,所以偏置值为 2^[8-1]-1 = 127
3490593.0 = 1101010100001100100001.0 = 1. 1010101000011001000010*2[21]
指数域 = (21+127)B = 1001 0100
小数域 = 1010 1010 0001 1001 0000 100
最终表示:
0 1001 0100 10101010000110010000100
符号 指数域(8) 小数域(23)
格式化为:
01001010 01010101 00001100 10000100

相关浮点类型通俗讲义文章:

https://blog.csdn.net/weixin_45500205/article/details/123661905

https://blog.csdn.net/weixin_45500205/article/details/124260139

https://blog.csdn.net/weixin_45500205/article/details/124332064

https://www.zhihu.com/people/ji-heng-62-36/posts