浮点数在计算机中的存储

转载于:浮点数在计算机中存储方式

对于浮点类型的数据采用单精度类型(float)和双精度类型(double)来存储,float数据占用32bit,double数据占用64bit,我们在声明一个变量float f= 2.25f的时候,是如何分配内存的呢?
答:存储方式上都是遵从IEEE的规范的,float遵从的是IEEE R32.24 ,而double 遵从的是R64.53。浮点数存储算术标准IEEE 754。

浮点数存储分为3部分

  1. 符号位(Sign): 0 0 0 为正, 1 1 1 为负数
  2. 指数位(Exponent):用于存储科学计数法中的指数数据,并且采用移位存储(如:float指数范围 f r o m − 127    t o   128 from -127~~to~ 128 from127  to 128,存储为 f r o m   0    t o    255 from~0~~to~~255 from 0  to  255)
  3. 尾数部分(Mantissa):…

在这里插入图片描述
R32.24和R64.53的存储方式都是用科学计数法来存储数据的,比如8.25用十进制的科学计数法表示就为: 8.25 ∗ 1 0 0 8.25*10^0 8.25100,而120.5可以表示为: 1.205 ∗ 1 0 2 1.205*10^2 1.205102。计算机根本以0-1方式存储,所以在计算机存储中,首先要将上面的数更改为二进制的科学计数法表示,8.25用二进制表示可表示为1000.01;120.5用二进制表示为:1110110.1(整数部分除二取余,小数部分乘二取整)。
用二进制的科学计数法表示1000.01可以表示为 1.00001 ∗ 2 3 1.00001*2^3 1.0000123; 1110110.1可以表示 为 1.1101101 ∗ 2 6 为1.1101101*2^6 1.110110126
任何一个数都的科学计数法表示都为 1. x x x ∗ 2 n 1.xxx*2^n 1.xxx2n,二进制下用科学计数法表示,整数部分肯定是 1 1 1,可以将小数点前面的1省略,所以 23 b i t 23bit 23bit 的尾数部分,可以表示的精度却变成了 24 b i t 24bit 24bit 。那 24 b i t 24bit 24bit 能精确到小数点后几位呢,我们知道9的二进制表示为1001,所以 4 b i t 4bit 4bit 能精确十进制中的1位小数点, 24 b i t 24bit 24bit 就能使 f l o a t float float 能精确到小数点后6位
指数部分,因为指数可正可负,8位的指数位能表示的指数范围就应该为:-127-128了,所以指数部分的存储采用移位存储,存储的数据为元数据+127这样都变为整数了

例子:
在这里插入图片描述
而双精度浮点数的存储和单精度的存储大同小异,不同的是指数部分和尾数部分的位数。

疑惑:

  float f = 2.2f;
  double d = (double)f;
  Console.WriteLine(d.ToString("0.0000000000000"));
  f = 2.25f;
  d = (double)f;
  Console.WriteLine(d.ToString("0.0000000000000"));
  
  单精度的2.2转换为双精度后,精确到小数点后13位后变为了2.2000000476837
  单精度的2.25转换为双精度后,变为了2.2500000000000

解答:
其实通过上面关于两种存储结果的介绍,我们已经大概能找到答案。首先我们看看 2.25 2.25 2.25 的单精度存储方式,很简单 01000000100100000000000000000000 0 1000 0001 001 0000 0000 0000 0000 0000 01000000100100000000000000000000 , 而 2.25 2.25 2.25 的双精度表示为: 0100000000010010000000000000000000000000000000000000000000000000 0 100 0000 0001 0010 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0100000000010010000000000000000000000000000000000000000000000000 ,这样 2.25 2.25 2.25 在进行强制转换的时候,数值是不会变的。
而我们再看看 2.2 2.2 2.2 呢, 2.2 2.2 2.2 用科学计数法表示应该为:将十进制的小数转换为二进制的小数的方法为将小数*2,取整数部分,所以 0.282 = 0.4 0.282=0.4 0.282=0.4 ,所以二进制小数第一位为 0.4 0.4 0.4 的整数部分 0 , 0.4 × 2 = 0.8 0,0.4×2=0.8 00.4×2=0.8 ,第二位为 0 , 0.8 ∗ 2 = 1.6 0,0.8*2=1.6 0,0.82=1.6 ,第三位为 1 1 1 0.6 × 2 = 1.2 0.6×2 = 1.2 0.6×2=1.2 ,第四位为 1 1 1 0.2 ∗ 2 = 0.4 0.2*2=0.4 0.22=0.4,第五位为 0 0 0 ,这样永远也不可能乘到=1.0,得到的二进制是一个无限循环的排列 00110011001100110011... 00110011001100110011... 00110011001100110011... , 对于单精度数据来说,尾数只能表示24bit的精度。
所以 1 / 2 n 1/2^n 1/2n的小数可以精确表示,且单双精度转换不会丢失或多小数。这主要由 十进制下小数部分 转换成 二进制的小数部分 的乘二取整的方法特性决定的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值