C 小数的存储方式

在C/C++中float是32位的,double是64位的,两者在内存中的存储方式和能够表示的精度均不同,目前C/C++编译器标准都遵照IEEE制定的浮点数表示法来进行float,double运算

无论是float还是double,在内存中的存储主要分成三部分,分别是:

(1)符号位(Sign):0代表正数,1代表负数

(2)指数位(Exponent):用于存储科学计数法中的指数部分,并且采用移位存储方式

(3)尾数位(Mantissa):用于存储尾数部分


对于两者在内存中的存储结构,如下图所示:



    数字float 9.125在十进制中用科学计算的方式表示为9.125*10^0  ,但是在计算机中,计算机只认识0和1,所以在计算机中是按照科学计算的二进制的方式表示的:

9的二进制表示为1001

0.125的二进制表示为0.001

所以9.125的表示成1001.001  将其表示成二进制的科学计数方式为 1.001001*2^


在计算机中,任何一个数都可以表示成1.xxxxxx*2^n 这样的形式,

其中xxxxx就表示尾数部分n表示指数部分

其中,因为最高位橙色的1这里,由于任何的一个数表示成这种形式时这里都是1,所以在存储时实际上并不保存这一位,这使得float的23bit的尾数可以表示24bit的精度,double中52bit的尾数可以表达53bit的精度。


    对于float型数据,可以精确到小数点后几位呢?当然,学过c的同学会说float能够精确到小数点后6位,但这是怎么的来的呢?下面做一点解释:

    十进制中的9,在二进制中的表示形式是1001,这里也就告诉我们,表示十进制中的一位数在二进制中需要4bit,所以我们现在float中具有24bit的精度,所以float在十进制中具有24/4=6,所以在十进制里,float能够精确到小数点后6位。同理,具有53bit精度的double类型能够精确到小数点后13位。

    对于float类型,他的指数部分有8bit,可以表示-127~128,但是这里采用了移位存储的方式(对这个概念不太清楚),在存储指数时数据的基数是127,而不是0,。例如上面的9.125,其二进制的指数部分为3,所以在存储时实际上存的是127+3=130。(130的二进制表示为10000010)

最终根据上面图中float的存储结构可以知道,实际上9.125在计算机中:


上面的二进制数转换成十六进制后表示形式为:01000001 00010000 00000000 00000000 --> 41 10 00 00

实际上在X86计算机中,采用的是小端存储方式,即低地址存储低位数据,高地址存储高位数据。

所以数据应该是这样存储的:


对于double类型的存储方式实际上和float是类似的,只是存储的位数不同,在原理上都是一样的。这个可以参考这篇博客



如有不清楚的还可以参考

http://www.360doc.com/content/12/0328/22/8265633_198759107.shtml


http://wenku.baidu.com/view/6f1d0b3131126edb6f1a101d.html


浮点数转二进制编码规则

354.75

354 = 101100010B

75 = 0.75 * 2 = 1.5 (1) = 0.5 * 2 = 1.0 = 结果 11B

354.75 = 101100010.11 这个要一直左移到整数部分为1

1.0110001011 * 10^8(左移了8) + 127 = 135

127数值的由来 浮点位是8位 取值范围是0~255

0-->127表示小数点向右移 128-->255表示向左移 127是它的中间值 

浮点位 135的二进制值 : 10000111

 

根据浮点编码规则得出

0 10000111 01100010110000000000000 

正负  点位置  数据

0100 0011 1011 0001 0110 0000 0000 0000

4     3    B     1    6   0    0     0

43 B1 60 00

根据小尾读法

00 60 B1 43

//-----下面是验证 

 

 

内存转小数的道理也是一样的

00 A8 1E 44 小尾读法 44 1E A8 00

44 1E A8 00

0100 0100 0001 1110 1010 1000 0000 0000

 

0 10001000 00111101010100000000000

正 136-127=9 1.00111101010100000000000

正 136-127=9 1001111010.101

正 136-127=9 2^9 + 2^6 + 2^5 + 2^4 + 2^3 + 2^1 + 2^-1 + 2^-3 = 512 + 64 + 32 + 16 + 8 + 2 + 0.5 + 0.125 = 634.625

//-----验证

 

 

 

C中 double 的存储规则

63位 正负

52-63位 点位置 共11

0-51  数据位 共52

它的特性跟float一样的



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值