文档库 最新最全的文档下载
当前位置:文档库 › IEEE754标准浮点数表示法

IEEE754标准浮点数表示法

IEEE754标准浮点数表示法
IEEE754标准浮点数表示法

IEEE754标准浮点数表示法[已验证正确性版本]

大家都知道任何数据在内存中都是以二进制(1或着0)顺序存储的,每一个1或着0被称为1位,而在x86CPU上一个字节是8位。比如一个16位(2字节)的short int型变量的值是1156,那么它的二进制表达就是:00000100 10000100。由于Intel CPU的架构是Little Endian(请参数机算机原理相关知识),所以它是按字节倒序存储的,那么就因该是这样:10000100 00000100,这就是定点数1156在内存中的结构。

那么浮点数是如何存储的呢?目前已知的所有的C/C++编译器都是按照IEEE(国际电子电器工程师协会)制定的IEEE 浮点数表示法来进行运算的。这种结构是一种科学表示法,用符号(正或负)、指数和尾数来表示,底数被确定为2,也就是说是把一个浮点数表示为尾数乘以2的指数次方再加上符号。下面来看一下具体的float的规格:

float

共计32位,折合4字节

由最高到最低位分别是第31、30、29、 0

31位是符号位,1表示该数为负,0反之。

30-23位,一共8位是指数位。

22-0位,一共23位是尾数位。

每8位分为一组,分成4组,分别是A组、B组、C组、D组。

每一组是一个字节,在内存中逆序存储,即:DCBA

我们先不考虑逆序存储的问题,因为那样会把读者彻底搞晕,所以我先按照顺序的来讲,最后再把他们翻过来就行了。

现在让我们按照IEEE浮点数表示法,一步步的将float型浮点数123456.0f转换为十六进制代码。在处理这种不带小数的浮点数时,直接将整数部转化为二进制表示:1 11100010 01000000也可以这样表示:11110001001000000.0然后将小数点向左移,一直移到离最高位只有1位,就是最高位的1:1.11100010010000000一共移动了16位,在布耳运算中小数点每向左移一位就等于在以2为底的科学计算法表示中指数+1,所以原数就等于这样:

1.11100010010000000 * ( 2 ^ 16 )好了,现在我们要的尾数和指数都出来了。显而易见,最高位永远是1,因为你不可能把买了16个鸡蛋说成是买了0016个鸡蛋吧?(呵呵,可别拿你买的臭鸡蛋甩我~),所以这个1我们还有必要保留他吗?(众:没有!)好的,我们删掉他。这样尾数的二进制就变成了:11100010010000000最后在尾数的后面补0,一直到补够23位:11100010010000000000000(MD,这些个0差点没把我数的背过气去~)

再回来看指数,一共8位,可以表示范围是0 - 255的无符号整数,也可以表示-128 - 127的有符号整数。但因为指数是可以为负的,所以为了统一把十进制的整数化为二进制时,都先加上127,在这里,我们的16加上127后就变成了143,二进制表示为:10001111 123456.0f这个数是正的,所以符号位是0,那么我们按照前面讲的格式把它拼起来:

0 10001111 11100010010000000000000

01000111 11110001 00100000 00000000

再转化为16进制为:47 F1 20 00,最后把它翻过来,就成了:00 20 F1 47。

现在你自己把54321.0f转为二进制表示,自己动手练一下!

有了上面的基础后,下面我再举一个带小数的例子来看一下为什么会出现精度问题。

按照IEEE浮点数表示法,将float型浮点数123.456f转换为十六进制代码。对于这种带小数的就需要把整数部和小数部分开处理。整数部直接化二进制:1111011。小数部的处理比较麻烦一些,也不太好讲,可能反着讲效果好一点,比如有一个十进制纯小数0.57826,那

么5是十分位,位阶是1/10;7是百分位,位阶是1/100;8是千分位,位阶是1/1000……,这些位阶分母的关系是10^1、10^2、10^3……,现假设每一位的序列是{S1、S2、S3、……、Sn},在这里就是5、7、8、2、6,而这个纯小数就可以这样表示:n = S1 * ( 1 / ( 10 ^ 1 ) ) + S2 * ( 1 / ( 10 ^ 2 ) ) + S3 * ( 1 / ( 10 ^ 3 ) ) + …… + Sn * ( 1 / ( 10 ^ n ) )。把这个公式推广到b进制纯小数中就是这样:

n = S1 * ( 1 / ( b ^ 1 ) ) + S2 * ( 1 / ( b ^ 2 ) ) + S3 * ( 1 / ( b ^ 3 ) ) + ……+ Sn * ( 1 / ( b ^ n ) )

天哪,可恶的数学,我怎么快成了数学老师了!没办法,为了广大编程爱好者的切身利益,喝口水继续!现在一个二进制纯小数比如0.100101011就应该比较好理解了,这个数的位阶序列就因该是1/(2^1)、1/(2^2)、1/(2^3)、1/(2^4),即0.5、0.25、0.125、0.0625……。乘以S序列中的1或着0算出每一项再相加就可以得出原数了。现在你的基础知识因该足够了,再回过头来看0.456这个十进制纯小数,化为该如何表示呢?现在你动手算一下,最好不要先看到答案,这样对你理解有好处。

我想你已经迫不及待的想要看答案了,因为你发现这跟本算不出来!来看一下步骤:1 / 2 ^1位(为了方便,下面仅用2的指数来表示位),0.456小于位阶值0.5故为0;2位,0.456大于位阶值0.25,该位为1,并将0.45减去0.25得0.206进下一位;3位,0.206大于位阶值0.125,该位为1,并将0.206减去0.125得0.081进下一位;4位,0.081大于0.0625,为1,并将0.081减去0.0625得0.0185进下一位;5位0.0185小于0.03125,为0……问题出来了,即使超过尾数的最大长度23位也除不尽!这就是著名的浮点数精度问题了。不过我在这里不是要给大家讲《数值计算》,用各种方法来提高计算精度,因为那太庞杂了,恐怕我讲上一年也理不清个头绪啊。我在这里就仅把浮点数表示法讲清楚便达到目的了。OK,我们继续。嗯,刚说哪了?哦对对,那个数还没转完呢,反正最后一直求也求不尽,加上前面的整数部算够24位就行了:1111011.01110100101111001。某BC问:“不是23位吗?”我:“倒,不是说过了要把第一个1去掉吗?当然要加一位喽!”现在开始向左移小数点,大家和我一起移,众:“1、2、3……”好了,一共移了6位,6加上127得131(怎么跟教小学生似的?呵呵~),二进制表示为:10000101,符号位为……再……不说了,越说越啰嗦,大家自己看吧:

0 10000101 11101101110100101111001

42 F6 E9 79

79 E9 F6 42

下面再来讲如何将纯小数转化为十六进制。对于纯小数,比如0.0456,我们需要把他规格化,变为1.xxxx * (2 ^ n )的型式,要求得纯小数X对应的n可用下面的公式:

n = int( 1 + log (2)X );

0.0456我们可以表示为1.4592乘以以2为底的-5次方的幂,即1.4592 * ( 2 ^ -5 )。转化为这样形式后,再按照上面第二个例子里的流程处理:

1. 01110101100011100010001

去掉第一个1

01110101100011100010001

-5 + 127 = 122

0 01111010 01110101100011100010001

最后:

11 C7 3A 3D

另外不得不提到的一点是0.0f对应的十六进制是00 00 00 00,记住就可以了。

最后贴一个可以分析并输出浮点数结构的函数源代码,有兴趣的自己看看吧:// 输入4个字节的浮点数内存数据

void DecodeFloat( BYTE pByte[4] )

{

printf( "原始(十进制):%d %d %d %d\n" , (int)pByte[0],

(int)pByte[1], (int)pByte[2], (int)pByte[3] );

printf( "翻转(十进制):%d %d %d %d\n" , (int)pByte[3],

(int)pByte[2], (int)pByte[1], (int)pByte[0] );

bitset<32> bitAll( *(ULONG*)pByte );

string strBinary = bitAll.to_string, allocator >();

strBinary.insert( 9, " " );

strBinary.insert( 1, " " );

cout << "二进制:" << strBinary.c_str() << endl;

cout << "符号:" << ( bitAll[31] ? "-" : "+" ) << endl;

bitset<32> bitTemp;

bitTemp = bitAll;

bitTemp <<= 1;

LONG ulExponent = 0;

for ( int i = 0; i < 8; i++ )

{

ulExponent |= ( bitTemp[ 31 - i ] << ( 7 - i ) );

}

ulExponent -= 127;

cout << "指数(十进制):" << ulExponent << endl;

bitTemp = bitAll;

bitTemp <<= 9;

float fMantissa = 1.0f;

for ( int i = 0; i < 23; i++ )

{

bool b = bitTemp[ 31 - i ];

fMantissa += ( (float)bitTemp[ 31 - i ] / (float)( 2 << i ) ); }

cout << "尾数(十进制):" << fMantissa << endl;

float fPow;

if ( ulExponent >= 0 )

{

fPow = (float)( 2 << ( ulExponent - 1 ) );

}

else

{

fPow = 1.0f / (float)( 2 << ( -1 - ulExponent ) );

}

cout << "运算结果:" << fMantissa * fPow << endl;

}

数的定点表示和浮点表示

计算机处理的数值数据多数带有小数,小数点在计算机常有两种表示方法,一种是约定所有数值数据的小数点隐含在某一个固定位置上,称为定点表示法,简称定点数;另一种是小数点位置可以浮动,称为浮点表示法,简称浮点数。 1. 定点数表示法(fixed-point) 所谓定点格式,即约定机器中所有数据的小数点位置是固定不变的。在计算机常采用两种简单的约定:将小数点的位置固定在数据的最高位之前,或者是固定在最低位之后。一般常称前者为定点小数,后者为定点整数。 定点小数是纯小数,约定的小数点位置在符号位之后、有效数值部分最高位之前。若数据x的形式为x=x0.x1x2… xn(其中x0为符号位,x1~xn是数值的有效部分,也称为尾数,x1为最高有效位),则在计算机中的表示形式为: 一般说来,如果最末位xn= 1,前面各位都为0,则数的绝对值最小,即|x|min= 2-n。如果各位均为1,则数的绝对值最大,即|x|max=1-2-n。所以定点小数的表示围是:

2-n≤|x|≤1 -2-n 定点整数是纯整数,约定的小数点位置在有效数值部分最低位之后。若数据x的形式为x=x0x1x2…xn(其中x0为符号位,x1~xn是尾数,xn为最低有效位),则在计算机中的表示形式为: 定点整数的表示围是: 1≤|x|≤2n-1 当数据小于定点数能表示的最小值时,计算机将它们作0处理,称为下溢;大于定点数能表示的最大值时,计算机将无法表示,称为上溢,上溢和下溢统称为溢出。 计算机采用定点数表示时,对于既有整数又有小数的原始数据,需要设定一个比例因子,数据按其缩小成定点小数或扩大成定点整数再参加运算,运算结果,根据比例因子,还原

浮点数的表示和基本运算

浮点数的表示和基本运算 1 浮点数的表示 通常,我们可以用下面的格式来表示浮点数 S P M 其中S是符号位,P是阶码,M是尾数 对于IBM-PC而言,单精度浮点数是32位(即4字节)的,双精度浮点数是64位(即8字节)的。两者的S,P,M所占的位数以及表示方法由下表可知 S P M表示公式偏移量 1823(-1)S*2(P-127)*1.M127 11152(-1)S*2(P-1023)*1.M1023 以单精度浮点数为例,可以得到其二进制的表示格式如下 S(第31位)P(30位到 23位) M(22位到 0位) 其中S是符号位,只有0和1,分别表示正负;P是阶码,通常使用移码表示(移码和补码只有符号位相反,其余都一样。对于正数而言,原码,反码和补码都一样;对于负数而言,补码就是其绝对值的原码全部取反,然后加1.) 为了简单起见,本文都只讨论单精度浮点数,双精度浮点数也是用一样的方式存储和表示的。 2 浮点数的表示约定 单精度浮点数和双精度浮点数都是用IEEE754标准定义的,其中有一些特殊约定。 (1) 当P = 0, M = 0时,表示0。 (2) 当P = 255, M = 0时,表示无穷大,用符号位来确定是正无穷大还是负无穷大。

(3) 当P = 255, M != 0时,表示NaN(Not a Number,不是一个数)。 当我们使用.Net Framework的时候,我们通常会用到下面三个常量 Console.WriteLine(float.MaxValue); // 3.402823E+38 Console.WriteLine(float.MinValue); //-3.402823E+38 Console.WriteLine(float.Epsilon); // 1.401298E-45 //如果我们把它们转换成双精度类型,它们的值如下 Console.WriteLine(Convert.ToDouble(float.MaxValue)); // 3.40282346638529E+38 Console.WriteLine(Convert.ToDouble(float.MinValue)); //-3.40282346638529E+38 Console.WriteLine(Convert.ToDouble(float.Epsilon)); // 1.40129846432482E-45 那么这些值是如何求出来的呢? 根据上面的约定,我们可以知道阶码P的最大值是11111110(这个值是254,因为255用于特殊的约定,那么对于可以精确表示的数来说,254就是最大的阶码了)。尾数的最大值是11111111111111111111111。 那么这个最大值就是:0 11111110 11111111111111111111111。 也就是 2(254-127) * (1.11111111111111111111111)2 = 2127 * (1+1-2-23) = 3.40282346638529E+38 从上面的双精度表示可以看出,两者是一致的。最小的数自然就是- 3.40282346638529E+38。 对于最接近于0的数,根据IEEE754的约定,为了扩大对0值附近数据的表示能力,取阶码P = -126,尾数 M = (0.00000000000000000000001)2 。此时该数的二进制表示为:0 00000000 00000000000000000000001 也就是2-126 * 2-23 = 2-149 = 1.40129846432482E-45。这个数字和上面的Epsilon 是一致的。 如果我们要精确表示最接近于0的数字,它应该是 0 00000001 00000000000000000000000 也就是:2-126 * (1+0) = 1.17549435082229E-38。 3 浮点数的精度问题 浮点数以有限的32bit长度来反映无限的实数集合,因此大多数情况下都是一个近似值。同时,对于浮点数的运算还同时伴有误差扩散现象。特定精度下看似

单精度浮点数的转换和解析

1 单精度浮点数的转换和解析 工业现场通信经常遇到浮点数解析的问题,如果需要自己模拟数据而又不懂浮点数解析的话会很麻烦!很久以前根据modbus 报文格式分析得到的,供大家参考。 浮点数保存的字节格式如下: 地址 +0 +1 +2 +3 内容 SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM 这里 S 代表符号位,1是负,0是正 E 偏移127的幂,二进制阶码=(EEEEEEEE)-127。 M 24位的尾数保存在23位中,只存储23位,最高位固定为1。此方法用最较少的位数实现了 较高的有效位数,提高了精度。 零是一个特定值,幂是0 尾数也是0。 浮点数-12.5作为一个十六进制数0xC1480000保存在存储区中,这个值如下: 地址 +0 +1 +2 +3 内容0xC1 0x48 0x00 0x00 浮点数和十六进制等效保存值之间的转换相当简单。下面的例子说明上面的值-12.5如何转 换。 浮点保存值不是一个直接的格式,要转换为一个浮点数,位必须按上面的浮点数保存格式表 所列的那样分开,例如: 地址 +0 +1 +2 +3 格式 SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM 二进制 11000001 01001000 00000000 00000000 十六进制 C1 48 00 00 从这个例子可以得到下面的信息: 符号位是1 表示一个负数 幂是二进制10000010或十进制130,130减去127是3,就是实际的幂。 尾数是后面的二进制数10010000000000000000000

浮点数的表示和运算(范围计算)

浮点数的表示和运算 浮点数的表示和基本运算 1 浮点数的表示 通常,我们可以用下面的格式来表示浮点数 其中S是符号位,P是阶码,M是尾数 对于IBM-PC而言,单精度浮点数是32位(即4字节)的,双精度浮点数是64位(即8字节)的。两者的S,P,M所占的位数以及表示方法由下表可知 以单精度浮点数为例,可以得到其二进制的表示格式如下 其中S是符号位,只有0和1,分别表示正负;P是阶码,通常使用移码表示(移码和补码只有符号位相反,其余都一样。对于正数而言,原码,反码和补码都一样;对于负数而言,补码就是其绝对值的原码全部取反,然后加1.) 为了简单起见,本文都只讨论单精度浮点数,双精度浮点数也是用一样的方式存储和表示的。 2 浮点数的表示约定 单精度浮点数和双精度浮点数都是用IEEE754标准定义的,其中有一些特殊约定。 (1)当P = 0, M = 0时,表示0。 (2)当P = 255, M = 0时,表示无穷大,用符号位来确定是正无穷大还是负无穷大。 (3)当P = 255, M != 0时,表示NaN(Not a Number,不是一个数)。 当我们使用.Net Framework的时候,我们通常会用到下面三个常量 Console.WriteLine(float.MaxValue); // 3.402823E+38 Console.WriteLine(float.MinValue); //-3.402823E+38 Console.WriteLine(float.Epsilon); // 1.401298E-45 //如果我们把它们转换成双精度类型,它们的值如下 Console.WriteLine(Convert.ToDouble(float.MaxValue)); // 3.40282346638529E+38 Console.WriteLine(Convert.ToDouble(float.MinValue)); //-3.40282346638529E+38 Console.WriteLine(Convert.ToDouble(float.Epsilon)); // 1.40129846432482E-45 那么这些值是如何求出来的呢?

32位浮点数转换为十进制

流量计计算机通过485端口以MODBUS协议把内部IEEE32位浮点数传送到DCS的数据经过研究试验,其数据格式如下 数据请求依次为:十六进制 从站地址:01;读命令:03;数据起始高位地址:0F;数据起始低位地址:A0;(0FA0=4000即地址44001);数据长度高位:00;数据长度低位:28;(0028=40即40个地址);CRC效验码:46,E2 数据应答格式: 从站地址:01;读命令反馈:03;数据长度:50;第一个地址:69;C0;48;A9;第二个地址:C5;00;48;A2;以下类推,直到最后两位CRC:E8;86 第一个地址:69;C0;48;A9是如何换算为346958的呢? 流量计发送的是IEEE标准的32位浮点数 首先要把69;C0;48;A9进行高低16位交换变成:48;A9;69;C0 变为32位二进制数:01001000 10101001 01101001 11000000 其中最高位为0,代表是正数 接下来的八位:10010001变成十进制是145,根据IEEE规范应减去127得18,这是小数点右移的位数; 剩下的23位是纯二进制小数即:0.0101001 01101001 11000000 加1后得1.0101001 01101001 11000000 小数点右移18位后得10101001 01101001 110.00000 变为十进制得346958 其它地址的32位浮点数计算方法同上 标题:《IEEE754 学习总结》 发信人:Vegeta 时间:2004-11-11,10:32 详细信息: 一:前言 二:预备知识 三:将浮点格式转换成十进制数 四:将十进制数转换成浮点格式(real*4) 附:IEEE754 Converte 1.0介绍 一:前言

浮点数的表示和计算

《计算机组成原理》实验报告

sw $aO, O($fp) #calculate the first nu mber andi $s2, $s0, 0x80000000 # s2 is the sig n srl $s2, $s2, 31 andi $s3, $s0, 0x7f800000 # s3 is the exp onent srl $s3, $s3, 23 andi $s4, $s0, 0x007fffff # s4 is the fractio n addi $s4, $s4, 0x00800000 #calculate the seco nd number andi $s5, $s1, 0x80000000 # s5 is the sig n srl $s5, $s5, 31 andi $s6, $s1, 0x7f800000 # s6 is the exp onent srl $s6, $s6, 23 andi $s7, $s1, 0x007fffff # s7 is the fractio n addi $s7, $s7, 0x00800000 sub $t0, $s3, $s6 bit $t0, 0, sumL1 # add sub bgt $t0, 0, sumL2 # sub add beq $t0, 0, sumL3 2.减法指令如下: mysub: subu $sp, $sp, 32 sw $ra, 20($sp) sw $fp, 16($sp) addiu $fp, $sp, 28 sw $a0, 0($fp) #calculate the first nu mber andi $s2, $s0, 0x80000000 # s2 is the sig n srl $s2, $s2, 31 andi $s3, $s0, 0x7f800000 # s3 is the exp onent srl $s3, $s3, 23 andi $s4, $s0, 0x007fffff # s4 is the fractio n addi $s4, $s4, 0x00800000 #calculate the seco nd number xori $s5, $s1, 0x80000000 # s5 is the sig n srl $s5, $s5, 31 andi $s6, $s1, 0x7f800000 # s6 is the exp onent srl $s6, $s6, 23 andi $s7, $s1, 0x007fffff # s7 is the fractio n addi $s7, $s7, 0x00800000 sub $t0, $s3, $s6 blt $t0, 0, subL1 # +,- bgt $t0, 0, subL2 # -,+ beq $t0, 0, subL3 # +,+ or -,- 3.乘法指令如下: mutilStart: srl $t2, $s0, 31 srl $t3, $s1, 31 sll $t4, $s0, 1

浮点转定点方法总结

浮点转定点方法总结 —孔德琦

目录 定点运算方法................................................ 错误!未定义书签。 数的定标 ............................................... 错误!未定义书签。 C语言:从浮点到定点 ................................. 错误!未定义书签。 加法.................................................... 错误!未定义书签。 乘法..................................................... 错误!未定义书签。 除法..................................................... 错误!未定义书签。 三角函数运算............................................ 错误!未定义书签。 开方运算................................................ 错误!未定义书签。 附录...................................................... 错误!未定义书签。 附录1:定点函数库...................................... 错误!未定义书签。 附录2:正弦和余弦表..................................... 错误!未定义书签。

浮点数表示方法与运算

在计算机系统的发展过程中,曾经提出过多种方法表达实数,典型的比如定点数。在定点数表达方式中,小数点位置固定,而计算机字长有限,所以定点数无法表达很大和很小的实数。最终,计算机科学发展出了表达范围更大的表达方式——浮点数,浮点数也是对实数的一种近似表达。 1.浮点数表达方式 我们知道任何一个R 进制数N 均可用下面的形式表示:N R =±S ×R ±e 其中,S—尾数,代表N 的有效数字; R—基值,通常取2、8、16;e—阶码,代表N 的小数点的实际位置(相当于数学中的指数)。 比如一个十进制数的浮点表达1.2345×102,其中1.2345为尾数,10为基数,2为阶码。一个二进制数的浮点表达0.001001×25,0.001001为尾数,2为基数,5为阶码;同时0.001001×25也可以表示成0.100100×23,0.100100为尾数,2为基数,3为阶码。浮点数就是利用阶码e 的变化达到浮动小数点的效果,从而灵活地表达更大范围的实数。 2.浮点数的规格化 一个数用浮点表示时,存在两个问题:一是如何尽可能多得保留有效数字;二是如何保证浮点表示的唯一。 对于数0.001001×25,可以表示成0.100100×23、0.00001001×27等等,所以对于同一个数,浮点有多种表示(也就是不能唯一表示)。另外,如果规定尾数的位数为6位,则0.00001001×27会丢掉有效数字,变成0.000010×27。因此在计算机中,浮点数通常采用规格化表示方法。 当浮点数的基数R 为2,即采用二进制数时,规格化尾数的定义为:1/2<=|S|<1。若尾数采用原码(1位符号位+n 位数值)表示,[S]原=S f S 1S 2S 3…S n (S f 为符号位的数符),则满足S 1=1的数称为规格化数。即当尾数的最高有效位S 1=1,[S]原=S f 1S 2S 3…S n ,表示该浮点数为规格化数。对0.001001×25进行规格化后,表示为0.100100×23。 3.浮点数的表示范围 求浮点数的表示范围,实质是求浮点数所能表示的最小负数、最大负数、最小正数和最大正数。

浮点数和定点数的区别

cloudseawang 定点数与浮点数区别 最近做HDR时,经常要用NV提供的16位纹理,它的说明书16位能达到24位的精度,就很奇怪?一直搞不懂浮点数的精度怎么算的? 今天认真看了一下IEEE float point的标准,终于明白是什么了 1. 什么是浮点数 在计算机系统的发展过程中,曾经提出过多种方法表达实数。典型的比如相对于浮点数的定点数(Fixed Point Number)。在这种表达方式中,小数点固定的位于实数所有数字中间的某个位置。货币的表达就可以使用这种方式,比如99.00 或者00.99 可以用于表达具有四位精度(Precision),小数点后有两位的货币值。由于小数点位置固定,所以可以直接用四位数值来表达相应的数值。SQL 中的NUMBER 数据类型就是利用定点数来定义的。还有一种提议的表达方式为有理数表达方式,即用两个整数的比值来表达实数。 定点数表达法的缺点在于其形式过于僵硬,固定的小数点位置决定了固定位数的整数部分和小数部分,不利于同时表达特别大的数或者特别小的数。最终,绝大多数现代的计算机系统采纳了所谓的浮点数表达方式。这种表达方式利用科学计数法来表达实数,即用一个尾数(Mantissa ),一个基数(Base),一个指数(Exponent)以及一个表示正负的符号来表达实数。比如123.45 用十进制科学计数法可以表达为1.2345 × 102 ,其中1.2345 为尾数,10 为基数,2 为指数。浮点数利用指数达到了浮动小数点的效果,从而可以灵活地表达更大范围的实数。 提示: 尾数有时也称为有效数字(Significand)。尾数实际上是有效数字的非正式说法。同样的数值可以有多种浮点数表达方式,比如上面例子中的123.45 可以表达为12.345 ×101,0.12345 × 103 或者1.2345 × 102。因为这种多样性,有必要对其加以规范化以达到统一表达的目标。规范的(Normalized)浮点数表达方式具有如下形式: ±d.dd...d × β e , (0 ≤ d i < β) 其中 d.dd...d 即尾数,β 为基数,e 为指数。尾数中数字的个数称为精度,在本文中用p 来表示。每个数字d 介于0 和基数之间,包括0。小数点左侧的数字不为0。 基于规范表达的浮点数对应的具体值可由下面的表达式计算而得: ±(d 0 + d 1β-1 + ... + d p-1β-(p-1))β e , (0 ≤ d i < β) 对于十进制的浮点数,即基数β 等于10 的浮点数而言,上面的表达式非常容易理解,也很直白。计算机内部的数值表达是基于二进制的。从上面的表达式,我们可以知道,二进制数同样可以有小数点,也同样具有类似于十进制的表达方式。只是此时β 等于2,而每个数字d 只能在0 和 1 之间取值。比如二进制数1001.101 相当于1 × 2 3 + 0 × 22 + 0 ×21 + 1 ×20 + 1 ×2-1 + 0 ×2-2 + 1 ×2-3,对应于十进制的9.625。其规范浮点数表达为1.001101 × 23。 2. IEEE 浮点数 计算机中是用有限的连续字节保存浮点数的。保存这些浮点数当然必须有特定的格式,Java 平台上的浮点数类型float 和double 采纳了IEEE 754 标准中所定义的单精度32 位浮点数和双精度64 位浮点数的格式。 注意: Java 平台还支持该标准定义的两种扩展格式,即float-extended-exponent 和double-extended-exponent 扩展格式。这里将不作介绍,有兴趣的读者可以参考相应的参考资料。 在IEEE 标准中,浮点数是将特定长度的连续字节的所有二进制位分割为特定宽度的符号域,指数域和尾数域三个域,其中保存的值分别用于表示给定二进制浮点数中的符号,

浮点数加减运算课件

如果一个二进制浮点数的尾数的绝对值小于1并且大于等于0.5,(1>|尾数|≥0.5),那么这个二进制浮点数就是一个规格化的浮点数。 用二进制补码表示1个规格化的浮点数,并且规格化的浮点数的尾数只有一个符号位时: 规格化的浮点数的尾数是正数时应该是0 . 1 X X X X X X X X X ……的形式 (0表示符号位,X表示0或1中的任意一个数值) 规格化的浮点数的尾数是负数时应该是1 . 0 X X X X X X X X X ……的形式 (1表示符号位,X表示0或1中的任意一个数值) 用二进制补码表示1个规格化的浮点数,并且规格化的浮点数的尾数只有两个符号位时: 规格化的浮点数的尾数是正数时应该是00 . 1 X X X X X X X X X ……的形式 (00表示符号位,X表示0或1中的任意一个数值) 规格化的浮点数的尾数是负数时应该是11 . 0 X X X X X X X X X ……的形式 (11表示符号位,X表示0或1中的任意一个数值) 两个浮点数加减法的计算结果必须规格化,如果不是规格化的数,则要通过修改阶码并同时左移或者右移尾数,使其变为规格化的数。 [例] x=2010×0.11011011,y=2100×-0.10101100,浮点数均以补码表示,阶码采用双符号位,尾数采用单符号位。求x+y 。 答: (步骤1)转换成题目中要求的浮点数格式: 浮点数x=2010×0.11011011的阶码是+010,尾数是+0.11011011 浮点数均以补码表示,所以阶码以补码表示,并且阶码采用双符号位, [x]浮的阶码=00010(00是两个符号位) 浮点数均以补码表示,所以尾数以补码表示,并且尾数采用单符号位, [x]浮的尾数=0.11011011(0是1个符号位)

非标准浮点数和标准的浮点数之间的转换

地址:安徽省、合肥市、肥东县、店埠镇,合肥市福来德电子科技有限公司Microchip 公司单片机所采用的浮点数格式是IEEE-754标准的变异型。 1、变异型32位浮点数格式为::阶码E (8位),符号S (1位),尾数M (23位) 变异型32位浮点数的二进制格式为::E7,E6,E5,E4,E4,E3,E2,E1,E0,S ,M22,M21,M20,M19,M18,M17,M16,M15,M14,M13,M12,M11,M10,M9,M8,M7,M6,M5,M4,M3,M2,M1,M0共计32位值。 存储模式 :大端格式,高字节存放在低地址位置。 2、标准型32位浮点数格式为::符号S (1位),阶码E (8位),尾数M (23位) 标准型32位浮点数的二进制格式为::S ,E7,E6,E5,E4,E4,E3,E2,E1,E0,M22,M21,M20,M19,M18,M17,M16,M15,M14,M13,M12,M11,M10,M9,M8,M7,M6,M5,M4,M3,M2,M1,M0共计32位值。 存储模式 :小端格式,高字节存放在高地址位置。 #include<18f6720.h> //#include //包含头文件string.h #include //包含头文件stdlib.h union { int8 b[4]; int32 d; //b[3]和d 的高8位值相等;b[0]和d 的低8位值相等; float f; }IEEE_FLOAT_DATA; //IEEE 标准型浮点数; union { int8 b[4]; int16 c[2]; int32 d; //b[3]和d 的高8位值相等;b[0]和d 的低8位值相等; float f; }IEEE_aberrance_FLOAT_DATA; //IEEE 变异型浮点数; //函数功能:将x 中的IEEE-754标准的浮点数转换为IEEE-754标准的变异型浮点数 //输入参数IEEE_FLOAT_DATA.d 中是标准型浮点数;IEEE_FLOAT_DATA.d=0xC148000 //输出参数:IEEE_FLOAT_DATA.f 存放为变异型浮点数据;IEEE_FLOAT_DATA.d 为变异型浮点数的16进制数据; void convert_IEEE_FLOAT_DATA_to_IEEE_aberrance_FLOAT_DATA() { //IEEE_FLOAT_DATA.d=x; int1 bit_value; int8 temp; if( bit_test(IEEE_FLOAT_DATA.b[2],7) ) bit_value=1; //获取阶码E0上的值; else bit_value=0; bit_value=shift_left(&IEEE_FLOAT_DATA.b[3],1,bit_value); //左移1位,将E0上的值移入,获取符号值S ; if(bit_value) bit_set(IEEE_FLOAT_DATA.b[2],7); //修改符号值S else bit_clear(IEEE_FLOAT_DATA.b[2],7); //修改符号值S ////////////////////////存储模式 ////////////

数的定点表示和浮点表示

计算机处理的数值数据多数带有小数,小数点在计算机中通常有两种表示方法,一种是约定所有数值数据的小数点隐含在某一个固定位置上,称为定点表示法,简称定点数;另一种是小数点位置可以浮动,称为浮点表示法,简称浮点数。 1. 定点数表示法(fixed-point) 所谓定点格式,即约定机器中所有数据的小数点位置是固定不变的。在计算机中通常采用两种简单的约定:将小数点的位置固定在数据的最高位之前,或者是固定在最低位之后。一般常称前者为定点小数,后者为定点整数。 定点小数是纯小数,约定的小数点位置在符号位之后、有效数值部分最高位之前。若数据x的形式为x=x0.x1x2… xn(其中x0为符号位,x1~xn是数值的有效部分,也称为尾数,x1为最高有效位),则在计算机中的表示形式为: 一般说来,如果最末位xn= 1,前面各位都为0,则数的绝对值最小,即|x|min= 2-n。如果各位均为1,则数的绝对值最大,即|x|max=1-2-n。所以定点小数的表示范围是:

2-n≤|x|≤1 -2-n 定点整数是纯整数,约定的小数点位置在有效数值部分最低位之后。若数据x的形式为x=x0x1x2…xn(其中x0为符号位,x1~xn是尾数,xn为最低有效位),则在计算机中的表示形式为: 定点整数的表示范围是: 1≤|x|≤2n-1 当数据小于定点数能表示的最小值时,计算机将它们作0处理,称为下溢;大于定点数能表示的最大值时,计算机将无法表示,称为上溢,上溢和下溢统称为溢出。 计算机采用定点数表示时,对于既有整数又有小数的原始数据,需要设定一个比例因子,数据按其缩小成定点小数或扩大成定点整数再参加运算,运算结果,根据比例因子,还原

浮点数的加减乘除运算步骤

设两个浮点数X=Mx※2Ex Y=My※2Ey 实现X±Y要用如下5步完成: ①对阶操作:小阶向大阶看齐 ②进行尾数加减运算 ③规格化处理:尾数进行运算的结果必须变成规格化的浮点数,对于双符号位的补码尾数来说,就必须是001×××…×× 或110×××…××的形式, 若不符合上述形式要进行左规或右规处理。 ④舍入操作:在执行对阶或右规操作时常用“0”舍“1”入法将右移出去的尾数数值进行舍入,以确保精度。 ⑤判结果的正确性:即阶码是否溢出 若阶码下溢(移码表示是00…0),要置结果为机器0; 若阶码上溢(超过了阶码表示的最大值)置溢出标志。 例题:假定X=0 .0110011*211,Y=0.1101101*2-10(此处的数均为二进制)?? 计算X+Y;解:[X]浮:0 1010 1100110 [Y]浮:0 0110 1101101 符号位阶码尾数 第一步:求阶差:│ΔE│=|1010-0110|=0100 第二步:对阶:Y的阶码小,Y的尾数右移4位 [Y]浮变为0 1010 0000110 1101暂时保存 第三步:尾数相加,采用双符号位的补码运算 00 1100110 +00 0000110 00 1101100 第四步:规格化:满足规格化要求 第五步:舍入处理,采用0舍1入法处理 故最终运算结果的浮点数格式为:0 1010 1101101, 即X+Y=+0. 1101101*210

①阶码运算:阶码求和(乘法)或阶码求差(除法) 即[Ex+Ey]移= [Ex]移+ [Ey]补 [Ex-Ey]移= [Ex]移+ [-Ey]补 ②浮点数的尾数处理:浮点数中尾数乘除法运算结果要进行舍入处理 例题:X=0 .0110011*211,Y=0.1101101*2-10 求X※Y 解:[X]浮:0 1 010 ******* [Y]浮:0 0 110 1101101 第一步:阶码相加 [Ex+Ey]移=[Ex]移+[Ey]补=1 010+1 110=1 000 1 000为移码表示的0 第二步:原码尾数相乘的结果为: 0 10101101101110 第三步:规格化处理:已满足规格化要求,不需左规,尾数不变,阶码不变。第四步:舍入处理:按舍入规则,加1进行修正 所以X※Y= 0.1010111※2+000

十进制数和单精度浮点数的相互转换

将十进制数转换成浮点格式(real*4) [例1]: 十进制26.0转换成二进制 11010.0 规格化二进制数 1.10100*2^4 计算指数 4+127=131 符号位指数部分尾数部分 0 10000011 10100000000000000000000 以单精度(real*4)浮点格式存储该数0100 0001 1101 0000 0000 0000 0000 0000 0x41D0 0000 [例2]: 0.75 十进制0.75转换成二进制 0.11 规格化二进制数 1.1*2^-1 计算指数 -1+127=126 符号位指数部分尾数部分 0 01111110 10000000000000000000000 以单精度(real*4)浮点格式存储该数0011 1111 0100 0000 0000 0000 0000 0000 0x3F40 0000 [例3]: -2.5 十进制-2.5转换成二进制 -10.1 规格化二进制数 -1.01*2^1 计算指数 1+127=128 符号位指数部分尾数部分 1 10000000 01000000000000000000000 以单精度(real*4)浮点格式存储该数1100 0000 0010 0000 0000 0000 0000 0000 0xC020 0000

将浮点格式转换成十进制数 [例1]: 0x00280000(real*4) 转换成二进制 00000000001010000000000000000000 符号位指数部分(8位)尾数部分 0 00000000 01010000000000000000000 符号位=0;因指数部分=0,则:尾数部分M为m: 0.01010000000000000000000=0.3125 该浮点数的十进制为: (-1)^0*2^(-126)*0.3125 =3.6734198463196484624023016788195e-39 [例2]: 0xC04E000000000000(real*8) 转换成二进制1100000001001110000000000000000000000000000000000000000000000000 符号位指数部分(11位)尾数部分 1 10000000100 1110000000000000000000000000000000000000000000000000 符号位=1;指数=1028,因指数部分不为全'0'且不为全'1',则:尾数部分M为1+m:1.1110000000000000000000000000000000000000000000000000=1.875 该浮点数的十进制为: (-1)^1*2^(1028-1023)*1.875 =-60

浮点数计算方式

2.3.4二进制转10进制及10进制转为二进制 【例2-3-4】 把二进制110.11转换成十进制数,及十进制转为二进制。 解: (110.11)2 =1×22+1×21+1×20+1×2-1+1×2-2 =4+2+0+0.5+0.25=(6.75)10 把十进制转换为二进制 解: 2 6 0 2 3 1 1 1 所以实数部分为110 0.75×(2×2-1)=0.75×2×2-1 =1×2-1+0.5×2-1 =1×2-1+1×2-2 所以结果为:(110.11)2 2.3.5 浮点数在计算机中存储形式 当前主流微机中广泛采用的IEEE754标准浮点格式。 按IEEE754标准,常用的浮点数(32位短实数)的格式如图2-3所示。

IEEE754标准浮点格式 N=2e.M (M为浮点尾数,为纯小数,e为浮点数的指数(阶码))尾数部分决定了浮点数的精度,阶码决定了表示范围32为浮点数(IEEE754标准格式0—22为尾数M,23-30为阶码E,31为符号位S),阶码用移码表示。阶码E=指数真值e+127 规格化真值x=(-1)^S*(1.M)*2^(E-127) 将(82.25)10 转换成短浮点数格式。 1)先将(82.25)10 转换成二进制数 (82.25)10 =(1010010.01)2 2)规格化二进制数(1010010.01)2 1010010.01=1.01001001×2 6 尾数M=01001001 3)计算移码表示的阶码=偏置值+阶码真值: E=127+6=133=10000101 4)以短浮点数格式存储该数 因此:符号位=0 S=0表示该数为正数 阶码=10000101 由3)可得 尾数=01001001000000000000000 由2)可得;尾数为23位, 不足在后面添15位0 所以,短浮点数代码为: 0;10000101;01001001000000000000000 表示为十六进制代码为:42A48000H

编写一个程序,将用小数表示的浮点数,转换成科学计数法的形式输出.输入的数据没有

不知道你问什么语言 Java:浮点数输出,不显示成科学计数法 BigDecimal bg=new BigDecimal("3.456785E-8"); System.out.println(bg.toPlainString()); C: public abstract class ScienceCount { public static string KXJSF(double num) { double bef = System.Math.Abs(num); int aft = 0; while (bef >= 10 || (bef < 1 && bef != 0)) { if (bef >= 10) { bef=bef/10; aft++; } else { bef=bef*10; aft--; } } Return string.Concat(num >=0 ?"" :"-",ReturnBef(bef),"E",ReturnAft(aft)); } ///

/// 有效数字的处理 /// /// 有效数字 /// 三位有效数字,不足则补零 public static string ReturnBef(double bef) {

if (bef.ToString() != null) { char[] arr = bef.ToString().ToCharArray(); switch (arr.Length) { case 1: case 2: return string.Concat(arr[0], ".", "00"); break; case 3: return string.Concat(arr[0] + "." + arr[2] + "0"); break; default: return string.Concat(arr[0] + "." + arr[2] + arr[3]); break; } } else { return "000"; } } ///

/// 幂的处理 /// /// 幂数 /// 三位幂数部分,不足则补零 public static string ReturnAft(int aft) { if (aft.ToString() != null) { string end; char[] arr = System.Math.Abs(aft).ToString().ToCharArray(); switch (arr.Length) { case 1: end = "00" + arr[0];

第7章DSP定点数和浮点数(重要)

第7章D S P定点数和浮点数(重要) 本期教程主要跟大家讲解一下定点数和浮点数的基础知识,了解这些基础知识对于后面学习ARM官方的DSP库大有裨益。特别是初学的一定要理解这些基础知识。 7.1 定点数和浮点数概念 7.2 IEEE浮点数 7.3 定点数运算 7.4总结 7.1定点数和浮点数概念 如果小数点的位置事先已有约定,不再改变,此类数称为“定点数”。相比之下,如果小数点的位置可变,则称为“浮点数”(定点数的本质是小数,整数只是其表现形式)。 7.1.1定点数 常用的定点数有两种表示形式:如果小数点位置约定在最低数值位的后面,则该数只能是定点整数;如果小数点位置约定在最高数值位的前面,则该数只能是定点小数。 7.1.2浮点数 在计算机系统的发展过程中,曾经提出过多种方法表达实数。典型的比如相对于浮点数的定点数(Fixed Point Number)。在这种表达方式中,小数点固定的位于实数所有数字中间的某个位置。货币的表达就可以使用这种方式,比如 99.00 或者 00.99 可以用于表达具有四位精度(Precision),小数点后有两位的货币值。由于小数点位置固定,所以可以直接用四位数值来表达相应的数值。SQL 中的 NUMBER 数据类型就是利用定点数来定义的。还有一种提议的表达方式为有理数表达方式,即用两个整数的比值来表达实数。 定点数表达法的缺点在于其形式过于僵硬,固定的小数点位置决定了固定位数的整数部分和小数部分,不利于同时表达特别大的数或者特别小的数。最终,绝大多数现代的计算机系统采纳了所谓的浮点数表达方式。这种表达方式利用科学计数法来表达实数,即用一个尾数(Mantissa ),一个基数(Base),一个指数(Exponent)以及一个表示正负的符号来表达实数。比如 123.45 用十进制科学计数法可以表达为 1.2345 × 102,其中 1.2345 为尾数,10 为基数,2 为指数。浮点数利用指数达到了浮动小数点的效果,从而可以灵活地表达更大范围的实数。 提示: 尾数有时也称为有效数字(Significand)。尾数实际上是有效数字的非正式说法。

浮点数转换为字符串

串口通讯中传递的数据格式不外两种:ASCII码(即可见字符形式)和二进制数据格式(对应Modbus协议中有ASCII模式和RTU模式)。最初的想法是把浮点数的各位分别提取出来,保存成一个各元素都是ASCII码的数组,然后通过串口发送出去,对方接收到这个数组后再相应地组合成原来的浮点数。这是以前写过的一段代码: //################################################################ // 函数名:void Float2Char(float Value,char *array) // 描述:将浮点数的各个位的数值转换成字符串,通过串口发送至上位机显示 // 参数:float Value为欲转换的正数浮点数值,转换结果保存在字符数组*array里 //################################################################ void Float2Char(float Value,char *array) { Uint16 IntegerPart; float DecimalPart; Uint16 i = 0; Uint16 j = 0; char temp; //分离整数部分与小数部分: //整数部分保存在IntegerPart中 //小数部分保存在DecimalPart中 if (Value>=1) { IntegerPart = (Uint16)Value; DecimalPart = Value-IntegerPart; } else { IntegerPart = 0; DecimalPart = Value-IntegerPart; } //转换整数部分 if (IntegerPart == 0) { array[0] = 0+48; array[1] = '.'; i = 1; } else { while(IntegerPart>0) {

相关文档
相关文档 最新文档