免费论文网 首页

双精度浮点性能

时间:2017-05-11 07:04 来源:免费论文网

篇一:单双精度浮点数的IEEE标准格式

单双精度浮点数的IEEE标准格式

目前大多数高级语言(包括C)都按照IEEE-754标准来规定浮点数的存储格式,IEEE754规定,单精度浮点数用4字节存储,双精度浮点数用 8字节存储,分为三个部分:符号位、阶和尾数。阶即指数,尾数即有效小数位数。单精度格式阶占8位,尾数占24位,符号位1位,双精度则为11为阶,53 位尾数和1位符号位,如下图所示:

31 3023 22 0

63 6252 51 0

细心的人会发现,单双精度各部分所占字节数量比实际存储格式都了一位,的确是这样,事实是,尾数部分包括了一位隐藏位,允许只存储23位就可以表示24位 尾数,默认的1位是规格化浮点数的第一位,当规格化一个浮点数时,总是调整它使其值大于等于1而小于2,亦即个位总是为1。例如1100B,对其规格化的 结果为1.1乘以2的三次方,但个位1并不存储在23位尾数部分内,这个1是默认位。

阶以移码的形式存储。对于单精度浮点数,偏移量为127(7FH),而双精度的偏移量为1023(3FFH)。存储浮点数的阶码之前,偏移量要先加到阶码 上。前面例子中,阶为2的三次方,在单精度浮点数中,移码后的结果为127+3即130(82H),双精度为1026(402H)。

浮点数有两个例外。数0.0存储为全零。无限大数的阶码存储为全1,尾数部分全零。符号位指示正无穷或者负无穷。

下面举几个例子:

所有字节在内存中的排列顺序,intel的cpu按little endian顺序,motorola的cpu按big endian顺序排列。

IEEE754标准的一个规格化 32位浮点数x的真值可表示为

x=(-1)^S*(1.M)*2^(E-127) e=E-127

3130 23 0

|S |E| M |

[例1]若浮点数x的754标准存储格式为(41360000)16,求其浮点数的十进制数值。

解:将16进制展开后,可得二进制数格式为

0 100,0001,0 011,0110,0000,0000,0000,0000

S E M

指数e=100,0001,0-01111111=00000011=(3)10

包含隐藏位1的尾数1.M=1.011,0110,0000,0000,0000,0000

于是有 x=(-1)^0*(1.M)*2^(E-127)

=+(1.011011)2*2^3

=(11.375)10

[例2]将数(20.59375)10转化为754标准的32位浮点数的二进制存储格式。 解:首先分别将整数部分和小数部分转换成二进制

(20.59375)10=+(10100.10011)2

然后移动小数点使其在1,2位之间

10100.10011=1.010010011*2^4 e=4

于是得到:S=0,E=e+127=131,M=010010011

最后得到32位浮点数的二进制存储格式为

0 100,0001,1 010,0100,1100,0000,0000,0000

=(41A4C000)16

从存储结构和算法上来讲,double和float是一样的,不一样的地方仅仅是float是32位的,double是64位的,所以double能存储更高的精度。

任何数据在内存中都是以二进制(0或1)顺序存储的,每一个1或0被称为1位,而在x86CPU上一个字节是8位。比如一个16位(2字节)的 short int型变量的值是1000,那么它的二进制表达就是:00000011 11101000。由于Intel CPU的架构原因,它是按字节 倒序存储的,那么就因该是这样:11101000 00000011,这就是定点数1000在内存中的结构。

目前C/C++编译器标准都遵照IEEE制定的浮点数表示法来进行float,double运算。这种结构是一种科学计数法,用符号、指数和尾数来表示,底数定为2——即把一个浮点数表示为尾数乘以2的指数次方再添上符号。下面是具体的规格:

````````符号位 阶码 尾数 长度

float 1 8 2332

double1 11 5264

临时数1 15 6480

由于通常C编译器默认浮点数是double型的,下面以double为例:

共计64位,折合8字节。由最高到最低位分别是第63、62、61、……、0位:

最高位63位是符号位,1表示该数为负,0正;

62-52位,一共11位是指数位;

51-0位,一共52位是尾数位。

^P

按照IEEE浮点数表示法,下面将把double型浮点数38414.4转换为十六进制代码。 把整数部和小数部分开处理:整数部直接化十六进制:960E。小数的处理:

0.4=0.5*0+0.25*1+0.125*1+0.0625*0+……

实际上这永远算不完!这就是著名的浮点数精度问题。所以直到加上前面的整数部分算够53位就行了(隐藏位技术:最高位的1不写入内存)。

如果你够耐心,手工算到53位那么因该是:

38414.4(10)=1001011000001110.0110101010101010101010101010101010101(2)

(注:实际上我也没算到那么位,这个也只是意思一下,所谓的55 55 55 55 CD C1 E2 40 对应却是38414.4166666666642……)科学记数法为:1.001……乘以2的15次方。指数为15! 于是来看阶码,一共11位,可以表示范围是-1024 ~ 1023。因为指数可以为负,为了便于计算,规定都先加上1023,在这里,15+1023=1038。二进制表示为:100 00001110 符号位:正—— 0 !

合在一起(尾数二进制最高位的1不要):

01000000 11100010 11000001 11001101 01010101 01010101 01010101 01010101

篇二:单双精度概念

单精度浮点数在机内占4个字节,用32位二进制描述。

双精度浮点数在机内占8个字节,用64位二进制描述。

浮点数在机内用指数型式表示,分解为:数符,尾数,指数符,指数四部分。

数符占1位二进制,表示数的正负。

指数符占1位二进制,表示指数的正负。

尾数表示浮点数有效数字,0.xxxxxxx,但不存开头的0和点

指数存指数的有效数字。

指数占多少位,尾数占多少位,由计算机系统决定。

可能是数符加尾数占24位,指数符加指数占8位 -- float.

数符加尾数占48位(C/C++是53),指数符加指数占16位(C/C++是11) -- double.

知道了这四部分的占位,按二进制估计大小范围,再换算为十进制,就是你想知道的数值范围。

对编程人员来说,double 和 float 的区别是double精度高,有效数字16位,float精度7位。但double消耗内存是float的两倍,double的运算速度比float慢得多,C语言中数学函数名称double 和 float不同,不要写错,能用单精度时不要用双精度(以省内存,加快运算速度)。

float尾数23,2^23=8388608,所以有效数字是七位,但是只能保证6位,因为7位表示不了全部。C++ primer也是这样说的,,double有效数字是十六位保证10位(第四版P32)。

在C++中,单精度浮点型(float )专指占用32位存储空间的单精度(single-precision )值。单精度在一些处理器上比双精度更快而且只占用双精度一半的空间,但是当值很大或很小的时候,它将变得不精确。当你需要小数部分并且对精度的要求不高时,单精度浮点型的变量是有用的。例如,当表示美元和分时,单精度浮点型是有用的。 在foxpro中,单精度浮点型是为了提供兼容性,浮点数据类型在功能上等价于数值型。

在VB中,Single 数据类型 Single(单精度浮点型)变量存储为 IEEE 32 位(4 个字节)浮点数值的形式,它的范围在负数的时候是从 -3.402823E38 到 -1.401298E-45,而在正数的时候是从 1.401298E-45 到 3.402823E38。

?

?

?

浮点数7位有效数字。

双精度数16位有效数字。

float浮点数取值范围:

负数取值范围为 -3.4028235E+38 到 -1.401298E-45,正数取值范围为 1.401298E-45 到 3.4028235E+38。

double数取值范围:

负值取值范围-1.79769313486231570E+308 到 -4.94065645841246544E-324,正值取值范围为 4.94065645841246544E-324 到 1.79769313486231570E+308。

C/C++中浮点数的表示遵循IEEE 754标准。

一个浮点数由三部分组成:符号位S、指数部分E(阶码)以及尾数部分M(如下)。

Floating

S--------E-------M

1位-----8位-----23位

Double

S--------E-------M

1位-----11位----52位

十进制数的换算计算公式为(n^m表示n的m次幂,B表示前面的数字是二进制):

S * 2^(E-127) * (1.M)B

浮点数的精度取决于尾数部分。尾数部分的位数越多,能够表示的有效数字越多。

单精度数的尾数用23位存储,加上默认的小数点前的1位1,2^(23+1) = 16777216。因为 10^7 < 16777216 < 10^8,所以说单精度浮点数的有效位数是7位。

双精度的尾数用52位存储,2^(52+1) = 9007199254740992,10^16 < 9007199254740992 < 10^17,所以双精度的有效位数是16位。

另外:

如果你在PI值的有效位后增加数字的话,结果是不会变化的,由于PI值是以常数方式赋值,可以在常数后面加个'f',如PI =

3.1415926f;否则编译器会先把常数当作double类型,然后再截断后面的值变为浮点值,这样的话,就有可能PI的值会有不同,造成你看到的现象。

篇三:浮点数(单精度浮点数与双精度浮点数)在计算机中的存储

浮点数在计算机中的存储

十进制浮点数格式:

浮点数格式使用科学计数法表示实数。科学计数法把数字表示为系数(coefficient)(也称为尾数(mantissa)),和指数 (exponent)两部分。比如 3.684*10^2. 在十进制中,指数的基数为 10,并且表示小数点移动多少位以生成系数。每次小数点向前移动时,指数就递增;每次小数点向后移动时,指数就递减。例如,25.92 可表示为 2.592 * 10^1,其中 2.592 是系数,值 10^1 是指数。必须把系数和指数相乘,才能得到原始的实数。另外,如 0.00172 可表示为 1.72*10^-3,数字 1.72 必须和 10^-3 相乘才能获得原始值。 二进制浮点格式:

计算机系统使用二进制浮点数,这种格式使用二进制科学计数法的格式表示数值。数字按照二进制格式表示,那么系数和指数都是基于二进制的,而不是十进制,例如 1.0101*2^2. 在十进制里,像 0.159 这样的值,表示的是 0 + (1/10) + (5/100) + (9/1000)。相同的原则也适用二进制。比如,1.0101 乘以 2^2 后,生成二进制值 101.01 ,这个值表示二进制整数 5,加上分数 (0/2) + (1/4) 。这生成十进制值 5.25 。下表列出几个二进制

编写二进制浮点值时,二进制通常被规格化了。这个操作把小数点移动到最左侧的数位,并且修改指针进行补偿。例如 1101.011 变成 1.101011*2^3

浮点数的存储

? IEEE 标准754 浮点数标准使用 3 个成分把实数定义为二进制浮点值: ? 符号

? 有效数字

? 指数

符号位表示值是负的还是正的。符号位中的 1 表示负值,0 表示正值。

有效数字部分表示浮点数的系数(coefficient)(或者说尾数(mantissa))。系数可以是规格化的(normalized),也可以是非规格化的(denormalized)。所谓规格化,就是任何一个数的科学计数法的表示都可为1.xxx*2^n,既然小数点左边的一位都是1,就可以把这一位省略。单精度浮点数23bit的尾数部分,可表示的精度却为24位,道理就在这里。

指数表示浮点数的指数部分,是一个无符号整数。因为指数值可以是正值,也可以是负值,所以通过一个偏差值对它进行置偏,及指数的真实值=指数部分的整数— 偏差值。对于32位浮点数,偏差值=127;对于64位浮点数,偏差值=1023.

浮点数的这 3 个部分被包含在固定长度的数据格式之内。IEEE 标准754 定义了浮点数的两种长度: 32位单精度 和 64位双精度

可以用于表示有效数字的位的数量决定精度。下图显示了两种不同精度类型的位布局:

单精度浮点使用 23 位有效数字值。但是,浮点格式假设有效数字的整数部分永远为 1 ,并且不在有效数字值中使用它。这样实际上有效数字的精度达到了 24 位。指数使用 8 位值,它的范围从 0~255,称为移码指数,意思是必须从指数中减去一个数(称为偏移量或者是偏差值),对单精度浮点数而言,这个值是 127 。当指数是0和255时,指数由别的含义,因此实际指数的范围是从 -126 到 +127 (二进制指数),这样整个浮点数的范围则为:(1.18 * 10^-38~1.0×2……-126 到 3.40 * 10^38~1.1……1×2^127)。

? 指数0和255用于特殊用途。如果指数从1变化到254,则由s(符号位)、e(指数)和f(有效数)来表示的数为:

?

? -1的 s 次幂是数学上的一种方法,意思是“如果 s 为0,则数是正的(因为任何数的 0 次幂等于 1 );如果 s 为 1,则数是负的(因为 -1的 1 次幂为 -1)”。

? 表达式的另一部分是1.f,意思是1后面为二进制小数点,再后面为23位的有效小数部分。它乘以2的幂,其中指数为内存中的8位移码指数减去127。

? 注意,还有一种特殊的情况 0 :

? 如果 e 等于 0,且 f 等于 0,则数为 0。通常,所有32位均为 0 则表示 0。但是符号位可以是 1,在这种情况下,数被解释为-0。-0 可以表示一个很小的数,小到在单精度格式中不能用数字和指数来表示。尽管如此,它们然小于 0。

? 如果 e 等于 0,且 f 不等于0

,则数是有效的。但是,它不是规格化的数,它等于

注意,二进制小数点左边的有效数为0。

? 如果e等于255,且f等于0,则数为正或负无穷大,这取决于符号s。

? 如果e等于255,且f不等于0,该值被认为“不是一个数”,简写为NaN。NaN可以表示一个不知道的数或者一个无效操作的结果。

Q:3.40 * 10^38 是值怎么来的?

A :在单精度浮点格式中可以表示的最大规格化的正或负二进制数为:

换算成 10 进制约等于:3.402823669e+38,这里 1.111...111 近似为 2,则 2 * 2^127 = 2^128 = 3.402823669e+38 .

Q:1.18 * 10^-38 的值是怎么来的?

A:通常,单精度浮点格式中可以表示的最小规格化的正或负二进制数为:

换算成 10 进制就是:1.175494351e-38,也就是约等于 1.18 * 10^-38 。

Q:单精度浮点24位换算为十进制后,为什么精度是 7 位?

A:10位二进制数近似等于3位十进制数。也就是说,若10位都置1(即十六进制为3FFh,十进制为1023),则它近似等于3位十进制都设置为9,即999。或者

:

这种关系表明按单精度浮点格式存放的24位二进制数大约与7位十进制数等效。因此,也可以说单精度浮点格式提供24位二进制精度,或大约7位十进制精度。可以这么设,一个 2 相当于 10^k 次方,即 10^k=2。那么 2 的 24 次方 2^24 = 10^24k 。从 10^k=2 可以知道 k = log10(2)~0.301。所以,2 的 24 次方换算到十进制,相当于有 24*log10(2)约等于 7.2 个精度 。

Q:262144.00 和 262144.01 是一样的么?

A:当然不是一样的!但是在计算机里,单精度的存储中,它们却是一样的!看这两个数作为单精度浮点数时在计算机里是怎么存储的: 两者被存储为同一个数字:。那这是为什么呢?原因是,规格化单精度浮点里,在小数点后有 23 位数,而 1.000...000 会经过 2^18 次方的运算后小数点会往前移动 18 个,那么小数点后面就只剩下 5 位,这时即使是 1/(2^5)=0.03125 都要比 0.01大,所以没办法,只能存为一样的数。

那么上面的问题如何避免呢?

答案是,使用双精度浮点数。

双精度浮点数的指数偏移量为1023,即3FFh,所以,以这种格式存放的数为:

它具有与单精度格式中所提到适用于0、无穷大和NaN等情形相同的规则。

最小的双精度浮点格式的正数或负数为:

最大的数为:

用十进制表示,它的范围近似为

。10的308

次幂是一个非常大的数,在1后面有308个十进制零。

53 位有效数(包括没有包含在内的那1位)的精度与16个十进制位表示的精度十分接近。相对于单精度浮点数来说这种表示要好多了,但它仍然意味着最终还是有一些数与另一些数是相等的。例如,140737488355328.00与140737488355328.01是相同的,这两个数按照64位双精度浮点格式存储,结果都是:42E0000000000000h

可把它转换为:

由上面可以看到,在双精度的浮点下,整数部分+小数部分的位数一共有 17 位。


双精度浮点性能
由:免费论文网互联网用户整理提供,链接地址:
http://m.csmayi.cn/meiwen/36226.html
转载请保留,谢谢!
相关阅读
最近更新
推荐专题