数在计算机中的存储
最近因项目需要对定点数进行计算,太久没有接触这方面知识了,故而将相关知识点进行整理汇总,以备后时之需。
预备知识
机器数
一个数在计算机中的二进制表示方式就是该数的机器数,它是将符号和数值绝对值一起数字化的数,它是有符号数,通过最高位(即符号位)表示正负,最高位为 0 表示正数,最高位为 1 表示负数
例如:
+3=0000 0011 和-3=1000 0011 便是机器数
机器数的真值
由于最高位表示符号位,因此一个机器数表示的真正数值不能直接从二进制转换为十进制,需要将符号位排除在外后再进行转换;转换后根据符号位添加正负号,将带符号位的机器数对应的数值称为机器数的真值,即真值为实际生活中使用到的数本身,例如+3,-3
例如:
0000 0011 的真值为+000 0011=+3,1000 0011 的真值为-000 0011=-3
原码、反码和补码
在计算机中,每个需要参加运算的数都需要以一定的编码方式进行存储,原码、反码和补码就是计算机存储数的编码方式,即机器数的表示形式为原码、反码和补码,除此之外还有移码
对于负整数或可以通过乘以 2 的幂次方转换为负整数$y$来说,设存储该负整数的位数为$n$,那么其补码就是$2^n+y$正整数的补码,也即原码
原码
原码就是符号位+数$x$绝对值的二进制,当数$x$为负数时符号位为 1,否则为 0
由于原码需要使用符号位表示数的正负,因此对于$n$位长度的原码表示的二进制数取值范围为$[-2^n+1,2^n-1]$
例如(以 8 位储存长度表示):
+3 的原码为 0000 0011,-3 的原码为 1000 0011
8 位长度原码表示的二进制数取值范围为$[-2^8+1,2^8-1]$=$[-127,127]$,即$[1111 1111, 0111 1111]$
反码
对于正数,反码就是原码
对于负数,反码在原码基础上对除符号位外的其他位进行取反操作
例如(以 8 位储存长度表示):
+3 的反码为 0000 0011,-3 的反码为 1111 1100
补码
补码是为了让符号位也作为数的一部分参与运算,将减法转换为加法,简化加减运算,对于反码来说,其实可以以加法代替减法,但是会出现 0 的符号问题以及 0 的两个编码问题,补码则成功解决了该问题
对于正数,补码就是原码
对于负数,补码则在反码基础上加 1
对于于$n$位长度的补码来说,可以表示的范围是$[-2^n,2^n-1]$,这是因为使用-0 的补码表示的$-2^n$,而$-2^n$并没有原码和补码
例如(以 8 位储存长度表示):
+3 的补码为 0000 0011,-3 的补码为 1111 1101
定点数和浮点数
定点数并不是仅仅只能表示整数,定点数也可以表示小数。 浮点数同样可以表示小数和整数;定点数和浮点数只是计算机表示数据的两种不同方式
定点数
定点数值小数点位置在计算机存储中是固定的,对于一个实数来说,对整数和小数部分分别使用补码表示即可(若该实数能通过乘以 2 的幂次方转换为整数,那将该整数转化为补码表示后再将小数点左移幂次方的位数即可得到该实数的定点数)
例如:
采用 s(8,3)有符号数格式表示:14.375(十进制)= 0101_1.110(二进制)
采用 s(8,3)有符号数格式表示:-3.25(十进制)= 1110_0.110(二进制)
采用 s(8,3)有符号数格式表示:3.25(十进制)= 0001_1.010(二进制)
采用 u(8,3)无符号数格式表示:24.125(十进制)= 1100_0.001(二进制)
浮点数
在计算机中,浮点数通常遵循 IEEE-754 标准。这个标准定义了浮点数的存储和运算方式,确保了不同计算机系统之间的一致性。IEEE-754 用以下形式来表示一个数:
$$
V = (-1)^s\times M\times2^E
$$
- s 符号位(Sign bit):表示数值的正负
- M 尾数(Mantissa):表示数值的有效数字
- E 指数(Exponent):决定小数点的位置
参考:
原码、反码、补码-知乎
真值、机器数、原码、补码、反码详解(你想知道的全都有!)_机器码和真值-CSDN 博客
机器数_百度百科
浮点数(有理数)_百度百科
浮点数与定点数理解、定点数转浮点数相互转换-CSDN 博客
浮点数详解(一篇彻底学通浮点数)-CSDN 博客
IEEE 754 浮点数标准详解 - C 语言中文网
754-2019 - IEEE Standard for Floating-Point Arithmetic
一文彻底掌握浮点数-知乎