在x86/x64体系里,由于x87 FPU硬件使用扩展双精度格式,因此必然会遇到single/double precision格式与double extended-precision格式之间的互换问题。
当由单精度数或双精度转换为扩展双精度数时,exponent部分必须基于扩展双精度数的biased码来调整。于是扩展双精度数的exponent值为:
① 从单精度转化:exponent – 127 + 16383。
② 从双精度转化:exponent – 1023 + 16383。
而扩展双精度数的significand部分,由单/双精度数的significand部分移植过来。
以单精度数1.11...×2120为例,它转换为扩展双精度的过程如下所示。
单精度数1.11...×2120的编码值为0x7BFFFFFF,它的exponent值为0xF7(11110111B),significand部分全为1值。
于是扩展双精度数的exponent值为0xF7-127 + 16383=0x4077(1000 0000 0111 0111B),单精度23位的significand部分直接移到扩展双精度的bit62到bit40位,低40位补0。
最终的扩展双精度编码值为0x4077_FFFFFF00_00000000。而对于双精度数来说:52位的significand部分将直接移到扩展双精度的bit62到bit11位。
而从扩展双精度转换为单/双精度数的情形会复杂得多,涉及目标格式的precison(精度)问题。当扩展双精度significand部分的值超出目标格式的精度时,就会发生rounded(舍入)操作,从而引发precision异常。
要检查超出精度的significand是否为0值,如下所示。
目标格式
|
超出精度部分
|
备注
|
单精度数
|
bit 39~bit 0
|
是否为0值
|
双精度数
|
bit 10~bit 0
|
这部分不为0值时,就会发生rounded操作。
下面,我们以扩展双精度数1.11...×2120转化为单精度格式为例进行描述。当1.11...×2120为扩展双精度格式时,它的编码值为0x4077_FFFFFFFF_FFFFFFFF。
目标格式exponent部分的计算如下。
① 单精度数:exponent-16383+127。
② 双精度数:exponent-16383+1023。
这个转换过程较为复杂,如下所示。
图中的阴影部分是超出精度的significand部分(bit 39~bit 0),它的值不为0,需要进行rounded操作,在x87 FPU中这个舍入依赖于rounded控制位。
IEEE754定义了以下4种舍入模式。
① round to nearest模式:朝±∞(正和负方向的无穷大值)方向舍入。
② round down模式:正数朝最大normal值舍入,负数朝-∞方向舍入。
③ round up模式:正数朝+∞方向舍入,负数朝最大normal值舍入。
④ round zero模式:正数和负数都朝最大normal值舍入。
上图中的舍入是朝+∞方向舍入,如图所示:bit 39的值为1,它将向bit 40进行舍入,效果等于+1值。目标格式中的significand部分舍入的结果值为0。
目标格式的exponent部分为扩展双精度的exponent-16383+127=0xF7(11110111B),可是由于significand部分还是进位值,因此目标格式的最终exponent部分为0xF8(加上1值)。
因此,最终转换的单精度值为0x7C000000,转换得到的浮点数是1.0...×2121,结果大于原来的扩展双精度浮点数。
这和转换为单精度数是一致的。在双精度格式里,它的精度是52位,因此超出精度部分为bit10到bit0位。
exponent的计算是扩展双精度的exponent-16383+1023。
本文节选自《x86x64体系探索及编程》
电子工业出版社出版
邓志著
分享到:
相关推荐
浮点数转换器,可将浮点数、单精度 双精度的数值转换为16进制发送
单精度双精度浮点数转换,浮点数与16进制转换工具
S7-200SMART_双精度浮点数转换为单精度浮点数库文件及使用说明
labview IEE754浮点数转换程序,通过串口采集到的十六进制字符串转换成单精度的浮点数,浮点数转换成十六进制字符串
双精度浮点数、单精度浮点数与十六进制,二进制之间可以进行任意转换
本代码将双精度浮点数转换为单精度浮点数,适合浮点数为正值的转换。 使用后将占用VD2810~VD2970字节,欢迎交流。 本代码的完成经历了一段时间的刻苦研究,无偿提供给真正需要的人,希望同行少走弯路。 代码允许复制...
绿色软件,免安装,解压即可使用。单精度浮点数转换工具
浮点数和十六进制数的相互转换,包括:1.单精度浮点数(32位)和十六进制数的相互转换,2.双精度浮点数(64位)和十六进制数的相互转换。
IEEE754浮点数,转换位十进制、二进制、字符串
单精度浮点数与十六进制转换_C语言程序__单片机也可用
自行设计,亲测无误,欢迎使用
因为要做一个MODBUS通讯的项目,在通讯要将仪表发来的数据转换成浮点数,又要将浮点数转换为 IEEE754的二进制表式形式发出去。网上查了很多都是一大段一大段的,但我认为这个是最简单明了的。 希望对做类似项目的人...
VBA实现单精度浮点数与十六进制字符串相互转换,并提供2个相互转换的示例 第一个按钮: "A1录入十六进制8位字符串; B1输出单精度浮点数结果" 第二个按钮 "将B1作为单精度浮点数输入 C1输出16进制结果
把一个单精度浮点数转换为十进制源码。如一个单精度:0x45a01f0a 转换后为5123.88
单精度浮点转换器用于把十进制,十六进制的单精度浮点相互转换
浮点数转换为十六进制的数值通常比较麻烦,这个小工具能够准确的进行计算
VC编程实现16进制浮点数转换为10进制,转换源代码,实验测试代码没有问题。符合IEEE754协议标准。
用C#写的32位浮点数转换成十进制小数程序。输入32位二进制数如01000000000000000000000000000000