整型-原反补
原码
原码是有符号整型最简单直接的编码方式,以8位二进制表示整型,最高位(从左向右第一位)为符号位。也就是说,有符号整型用7个比特位来表示大小,用1个比特位来表示正负。
符号位为0表示正数,为1则表示负数。比如:
+11的原码为00001011,-11的原码是10001011
原码对人来说简单易懂,但负数的原码并不适合直接拿给加法器计算:
1+(-1)=0
00000001+10000001=10000010
10000010换算为10进制是-2,显然不等于0,计算出错
为此,需要将负数的原码分两步转化为补码这一适合加法器处理的形式,而正数的原码直接作为其补码。
反码
负数的原码在转化为补码之前,首先应转化为反码,将除符号位以外每一位都取反:
-1→原码→反码
-1→10000001→11111110
补码
将获得的负数的反码加上1,便得到了最终产物补码:
-1反码→补码
-1→11111110→11111111
用补码进行之前的运算:
1+(-1)=0
00000001+11111111=00000000,0为全0,结果正确
大小端
以C语言为例,除了8 bit的char之外,还有16 bit的short型,32 bit的long型(要看具体的编译器)。另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,必然存在着一个如何将多个字节安排的问题,也就有了大端和小端这两种不同的存储顺序。
大端模式,是指数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址中,这一模式比较符合人的阅读习惯。
小端模式,是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中,与大端模式相反。
我们常用的 X86 结构是小端模式,以VS2017进行测试为例:
如图所示,在小端模式下整型1在内存按地址从低到高保存为01 00 00 00。
若为大端模式,则会保存为00 00 00 01。
根据这一特点我们可以使用字符类型来取整型1的第一个字节,通过检查所取结果是00还是01来判断当前环境是大端还是小端。关于实现这一功能的代码,可以参考我的另一篇chun文dai章ma:[C练习]函数检测大小端
浮点型-IEEE754
为了设计和制造等方面的效率,常见CPU只使用二进制加法器来实现四则运算等各种计算功能。在此结构上实现浮点数计算的方法可以有很多种,而目前最广泛使用的是IEEE754标准。
IEEE754规定,任意一个二进制浮点数V可以表示成下面的形式:
(-1)^S * M * 2^E
(-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。
M表示有效数字,大于等于1,小于2。
2^E表示指数位。
如图,单精度浮点型由1位符号位+8位阶码+23位尾数共计32比特位表示,而双精度浮点型由1位符号位+11位阶码+52位尾数共计64比特位来表示。
以单精度存储的0x41360000为例:
0x41360000
0 10000010 011 0110 0000 0000 0000 0000
符号位S=0
指数E=阶码-127=1000 0010-127=130-127=3
尾数1.M=1.011 0110 0000 0000 0000 0000
所以0x41360000=1.011011x2^3=+1011.011=(11.375)(十进制)
除单双两种精度外,还有使用更多位的扩展精度,比如常见的CPU内就使用比64位更高的扩展精度来进行浮点数计算,而计算结果四舍五入为精度较低的单或双精度,以尽可能减小浮点数计算的误差。
参考来源:百度百科,google,IEEE 754 浮点数的表示方法.