美文网首页
c语言单精度和双精度存储方式以及移位存储的优点

c语言单精度和双精度存储方式以及移位存储的优点

作者: 好多个胖子 | 来源:发表于2017-08-28 17:32 被阅读400次

存储方式

方式 位数 标准 模式
float 32bit IEEE R32.24 float.png
double 64bit R64.53 double.png
  1. 符号位(Sign):0代表正,1代表为负;
  2. 指数位(Exponent):用于存储科学计数法中的指数数据,并且采用移位存储;
  3. 尾数部分(Mantissa):尾数部分

R32.24和R64.53的存储方式都是用科学计数法来存储数据的
用二进制的科学计数法第一位都是1,可以将小数点前面的1省略,所以23bit的尾数部分,可以表示的精度却变成了 24bit,道理就是在这里。

那24bit能精确到小数点后几位呢,我们知道9的二进制表示为1001,所以4bit能精确十进制中的小数点后一位,24bit就能使float能精确到小数点后6位,而对于指数部分,因为指数可正可负,8位的指数位能表示的指数范围就应该为:-127-128了, 所以指数部分的存储采用移位存储,存储的数据为元数据+127。

下面就看看8.25和120.5在内存中真正的存储方式:

8.25换算成二进制科学计数法

8 = 1000;
0.25 = 0.01;

8.25(10) = 1000.01(2) = 1.00001*2^3 

  
按照上面的存储方式
符号位为   0,表示为正;
指数位为   3+127=130,
尾数部分为 00001 = 00001000000000000000000 //23位
故8.25的存储方式如下:
0--10000010--00001000000000000000000  
即01000001000001000000000000000000 


#同理

120.5在内存中的存储格式如下 
0--10000101--11100010000000000000000

即01000010111100010000000000000000 
 

那么如果给出内存中一段数据,并且告诉你是单精度存储的话,你如何知道该数据的十进制数值 呢?其实就是对上面的反推过程,比如给出如下内存数据:

01000001001000100000000000000000 
第一步:符号位为0,表示是正数;  
第二步:指数位为10000010,换算成十进制为130,所以指数为130-127=3; 
第三步:尾数位为01000100000000000000000,换算成十进制为 (1+1/4+1/64);
#尾数部分都要+1  
十进制数值为:2^3*(1+1/4+1/64)=8+2+1/8=10.125

移位存储的详解

以32位单精度float内存模型为例

float-struct.png

从上图可以看出 指数部分8位存储空间实际上并不在意同一个字节上,通常情况下8位存储空间可以存储的数值范围为

0000000 0 ~ 1111111 1

也就是从0开始到 255结束,一共 256个数。

但是新组成的8位数是用来表示整串32位单精度浮点数的幂指数(阶码)的,而浮点数的幂指数(阶码)是有必要使用负数的。

既要表示正数,又要表示负数,因此我们要拿出一位来表示正负号,通常都是拿一个字串最左边的那位即最高位来表示正负号的,使用传统的方式,即一个字节的最高位(最左边那位)为1时表示负数,那么我们可以得到两个区间,这里我们为了看着方便还是使用空格来隔开最高位的符号位和最低位的那位特殊位:

第一个区间:

0 000000 0~ 0 111111 1

即+ 0 到 127,

第二个区间:

1 000000 0~ 1 111111 1

即 -0 到 - 127,

这里出现了2个0,一个正+0,一个-0

使用移位存储方式会有什么效果呢? 移位存储要+127 , 存储示例:

127 使用这个新生成的字节来表示,则是:

0 111111 1 ,


如果我们要表示 0,则有 0+127=127 即 0 111111 1

:0 000000 0 + 0 111111 1= 0 111111 1


我们要表示1,则有 1+127=128 即 1 000000 0

:0 000000 1 + 0 111111 1= 1 000000 0

我们要表示 2,则有 2+127=129 即 1 000000 1

:0 000001 0 + 0 111111 1= 1 0000001

………………………………………………………………

我们要表示 128,则有 128+127=255 即 1 111111 1

:1 000000 0+ 0 111111 1= 1 111111 1

这个128是我们能够使用 8位二进制移位存储算法表示的最大的正数了,再大就溢出了。 同样,我们来看看负数:

我们要表示 -1时,则有( -1) +127=127-1=126 即 0 111111 0

:0 111111 1 - 0 000000 1= 0 111111 1

我们要表示 -2时,则有( -2)+ 127=127-2=125 即 0 111110 1

:0 111111 1 - 0 000001 0= 0 111110 1

……………………………………………………………………………………………… 我们要表示 -127时,则有(-127)+127=127-127=0 即 0 000000 0

:0 111111 1 - 0 111111 1= 0 000000 0

这-127,是我们能够使用 8位二进制采用移位存储所能表示的最小的负数了,再小就溢出。

由上面的 例子,我们可以得出规律,采用移位存储技术,我们可以使用 8位二进制来表示从 -127~128 共计:

127个负数+零(0)+128个正数=256个数

看来使用移位存储即没有+0和-0的问题,又充分的使用这个新生成的 8位二进制数来最大限度的表示单精度浮点数的幂指数(阶码),是非常合理的

相关文章

  • c语言单精度和双精度存储方式以及移位存储的优点

    存储方式 符号位(Sign):0代表正,1代表为负; 指数位(Exponent):用于存储科学计数法中的指数数据,...

  • 浮点数的表示

    语言和C#语言中,对于浮点类型的数据采用单精度类型(float)和双精度类型(double)来存储,float数据...

  • C语言学习 - 浮点型数据类型

    在 C语言中,浮点型数据类型可分为:float(单精度)、double(双精度)、long double(长双精度...

  • iOS浮点数精度问题

    前言 浮点数是无法精确表示大部分实数的 单精度浮点数和双精度浮点数 单精度(float),一般在计算机中存储占用4...

  • 新手小白整理C语言笔记备忘,带你十分钟理解C语言

    一.C语言数据类型 1.基本类型:整型、浮点型(单精度、双精度)、字符型和枚举类型; 2.构造类型:数组类型、结构...

  • iOS开发技能树之C语言-存储方式、类别

    存储方式 C语言根据变量的生存周期来区分,分为静态存储方式和动态存储方式。 静态存储方式:在程序运行期间分配固定存...

  • java基础-浮点数陷阱

    计算机的数值采用的是二进制形式存储。根据IEEE754标准,单精度浮点数为32位: 双精度浮点数为64位: 0.9...

  • 源铸:数值处理问题

    一、数值存储计算方案 高精度浮点数 采用双精度浮点数是最简单的存储方案,数据库支持,编程语言也支持。只要数据库和编...

  • Python

    基本类型 1. Number类型 整数: int 浮点数: float(双精度) 其他语言: 单精度(float)...

  • Intel x87 FPU的使用基础

    Intel x87 FPU专门用于执行标量浮点计算,可以对单精度浮点(32位)、双精度浮点(64位)以及扩展双精度...

网友评论

      本文标题:c语言单精度和双精度存储方式以及移位存储的优点

      本文链接:https://www.haomeiwen.com/subject/pcmgdxtx.html