当前位置:文档之家› 2.浮点数的存储原理

2.浮点数的存储原理

2.浮点数的存储原理
2.浮点数的存储原理

问题:long和float类型都是四个字节,为什么存储数值的范围相差极大?

原因:因为两者的存储原理时不同的。

浮点数的存储原理

作者: jillzhang

联系方式:jillzhang@https://www.doczj.com/doc/0415925472.html,

本文为原创,转载请保留出处以及作者,谢谢

C语言和C#语言中,对于浮点类型的数据采用单精度类型(float)和双精度类型(double)来存储,float数据占用32bit,double数据占用64bit,我们在声明一个变量float f= 2.25f的时候,是如何分配内存的呢?如果胡乱分配,那世界岂不是乱套了么,其实不论是float还是double在存储方式上都是遵从IEEE的规范的,float遵从的是IEEE R32.24 ,而double 遵从的是R64.53。

无论是单精度还是双精度在存储中都分为三个部分:

1.符号位(Sign) : 0代表正,1代表为负

2.指数位(Exponent):用于存储科学计数法中的指数数据,并且采用移位存储

3.尾数部分(Mantissa):尾数部分

其中float的存储方式如下图所示:

而双精度的存储方式为:

R32.24和R64.53的存储方式都是用科学计数法来存储数据的,比如8.25用十进制的科学计数法表示就为:8.25*,而120.5可以表示为:1.205*,这些小学的知识就不用多说了吧。而我们傻蛋计算机根本不认识十进制的数据,他只认识0,1,所以在计算机存储中,首先要将上面的数更改为二进制的科学计数法表示,8.25用二进制表示可表示为1000.01,我靠,不会连这都不会转换吧?那我估计要没辙了。120.5用二进制表示为:1110110.1用二进制的科学计数法表示1000.01可以表示为1.0001* ,1110110.1可以表示为1.1101101*,任何一个数都的科学计数法表示都为1.xxx*,尾数部分就可以表示为xxxx,第一位都是1嘛,干嘛还要表示呀?可以将小数点前面的1省略,所以23bit的尾数部分,可以表示的精度却变成了24bit,道理就是在这里,那24bit能精确到小数点后几位呢,我们知道9的二进制表示为1001,所以4bit能精确十进制中的1位小数点,24bit就能使float能精确到小数点后6位,而对于指数部分,因为指数可正可负,8位的指数位能表示的指数范围就应该为:-127-128了,所以指数部分的存储采用移位存储,存储的数据为元数据+127,下面就看看8.25和120.5在内存中真正的存储方式。

首先看下8.25,用二进制的科学计数法表示为:1.0001*

按照上面的存储方式,符号位为:0,表示为正,指数位为:3+127=130 ,位数部分为,故8.25的存储方式如下图所示:

而单精度浮点数120.5的存储方式如下图所示:

那么如果给出内存中一段数据,并且告诉你是单精度存储的话,你如何知道该数据的十进制数值呢?其实就是对上面的反推过程,比如给出如下内存数据:0100001011101101000000000000,首先我们现将该数据分段,0 10000 0101 110 1101 0000 0000 0000 0000,在内存中的存储就为下图所示:

根据我们的计算方式,可以计算出,这样一组数据表示为:1.1101101*=120.5

而双精度浮点数的存储和单精度的存储大同小异,不同的是指数部分和尾数部分的位数。所以这里不再详细的介绍双精度的存储方式了,只将120.5的最后存储方式图给出,大家可以仔细想想为何是这样子的

下面我就这个基础知识点来解决一个我们的一个疑惑,请看下面一段程序,注意观察输出结果

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.2在转换后的数值更改了而2.25却没有更改呢?很奇怪吧?其实通过上面关于两种存储结果的介绍,我们已经大概能找到答案。首先我们看看2.25的单精度存储方式,很简单 0 1000 0001 001 0000 0000 0000 0000 0000,而2.25的双精度表示为:0 100 0000 0001 0010 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000,这样2.25在进行强制转换的时候,数值是不会变的,而我们再看看2.2呢,2.2用科学计数法表示应该为:将十进制的小数转换为二进制的小数的方法为将小数*2,取整数部分,所以0.282=0.4,所以二进制小数第一位为0.4的整数部分0,0.4×2=0.8,第二位为0,0.8*2=1.6,第三位为1,0.6×2 = 1.2,第四位为1,0.2*2=0.4,第五位为0,这样永远也不可能乘到=1.0,得到的二进制是一个无限循环的排列 00110011001100110011... ,对于单精度数据来说,尾数只能表示24bit的精度,所以2.2的float存储为:

但是这样存储方式,换算成十进制的值,却不会是2.2的,应为十进制在转换为二进制的时候可能会不准确,如2.2,而double类型的数据也存在同样的问题,所以在浮点数表示中会产生些许的误差,在单精度转换为双精度的时候,也会存在误差的问题,对于能够用二进制表示的十进制数据,如2.25,这个误差就会不存在,所以会出现上面比较奇怪的输出结果。

本文属作者原创,只发布在博客园,希望大家在转载的时候,注明出处和作者,谢谢。

C语言float类型浮点数的存储方法

C语言float类型浮点数的存储方法 #include int main(int argc, char *argv[]) { float p = 5.1f; int f = (int)(p*100); printf("%d", f); getch(); return 0; } 我想要输出 510,可是机器居然输出509。 我试着把5.1改成5.5,一切正常。 IEEE规定的浮点数的机器表示: 32位机器的 float 是4字节的,共32位。 第1位是符号位,接着8位指数位,接着23位基数位。 以5.1为例。 5 = 101 (2进制) 0.1 = 0.0 0011 0011 0011 0011 0011 0011 .....(无限循环) 所以 5.1 = 101.0 0011 0011 0011 0011 0011 0011 0011 0011 ... 5.1= 1.010 0011 0011 0011 0011 0011 0011 0011 0011 0011... * 2^2 因为第一位总是为1,如果是0,就移动小数点直到是非0的,所以第一位的1丢弃。得到 010 0011 0011 0011 0011 0011 0011 0011 0011.... 取23位得到 0100 0110 0110 0110 0110 011 接着看指数部分 指数是2, 根据规定,指数统一+127再转换为无符号8位2进制数, 2+127=129 (1000 0001) 存储的时候指数部分存储在基数之前,这样就有31位了, 因为5.1是正的,所以符号为是0,存储在指数部分之前 这样就得到 0100 0000 1010 0011 0011 0011 0011 0011 我们来看一下机器上是否真的如此 #include #include int main(int argc, char *argv[])

浮点数存储

浮点数存储.txt世上最珍贵的不是永远得不到或已经得到的,而是你已经得到并且随时都有可能失去的东西!爱情是灯,友情是影子。灯灭时,你会发现周围都是影子。朋友,是在最后可以给你力量的人。浮点数: 浮点型变量在计算机内存中占用4字节(Byte),即32-bit。遵循IEEE-754格式标准。一个浮点数由2部分组成:底数m 和指数e。 ±mantissa × 2exponent (注意,公式中的mantissa 和 exponent使用二进制表示) 底数部分使用2进制数来表示此浮点数的实际值。 指数部分占用8-bit的二进制数,可表示数值范围为0-255。 指数应可正可负,所以IEEE规定,此处算出的次方须减去127才是真正的指数。所以float 的指数可从 -126到128 底数部分实际是占用24-bit的一个值,由于其最高位始终为 1 ,所以最高位省去不存储,在存储中只有23-bit。 到目前为止,底数部分 23位加上指数部分 8位使用了31位。那么前面说过,float是占用4个字节即32-bit,那么还有一位是干嘛用的呢?还有一位,其实就是4字节中的最高位,用来指示浮点数的正负,当最高位是1时,为负数,最高位是0时,为正数。 浮点数据就是按下表的格式存储在4个字节中: Address+0 Address+1 Address+2 Address+3 Contents SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM S: 表示浮点数正负,1为负数,0为正数 E: 指数加上127后的值的二进制数 M: 24-bit的底数(只存储23-bit) 注意:这里有个特例,浮点数为0时,指数和底数都为0,但此前的公式不成立。因为2的0次方为1,所以,0是个特例。当然,这个特例也不用认为去干扰,编译器会自动去识别。 举例1:计算机存储中的二进制数如何转换成实际浮点数 通过上面的格式,我们下面举例看下-12.5在计算机中存储的具体数据: Address+0 Address+1 Address+2 Address+3 Contents 0xC1 0x48 0x00 0x00 接下来我们验证下上面的数据表示的到底是不是-12.5,从而也看下它的转换过程。 由于浮点数不是以直接格式存储,他有几部分组成,所以要转换浮点数,首先要把各部分的值分离出来。 Address+0 Address+1 Address+2 Address+3 格式 SEEEEEEE EMMMMMMM MMMMMMMM MMMMMMMM

浮点数规格化和教案

第一节 X=(-1)S×(1.M)×2E-127e=E-127 X=(-1)S×(1.M)×2E-1023 e=E-1023 我承认以前对这俩公式避之不及不予深究努力自己说服自己而未能得逞,部分原因是跟“移码与真值的关系”扯上关系,这“移码与真值的关系”想搞清先得把引入移码的充分理由给我个说法,不幸玩过头正事误了。上回说了“补码省心移码悦目”能算是今时不同往日了吧,现在轮到对IEEE754浮点数规格化表示法杀无赦去死吧。 首先,“IEEE规格化形式”是对“传统规格化形式”进一步严格要求来的。 IEEE规格化形式唯一,而浮点数记法多种多样。 (1.75)10=1.11×20 (IEEE规格化表示)=0.111×21 (传统规格化表示) =0.0111×22=0.00111×23 其次,既然IEEE想到对“传统规格化形式”进一步修订当然有目的,你以为作无用功呐,关键目的是什么? 规格化的目的同理。修改阶码同时左右移小数点使尾数域最高有效位固定为1,尾数就以ta所可能变化成的最大形式出现,即使遭遇类似截断的操作仍可保持尽可能高的精度。 有类错误我这种大秀逗极善于犯!就是不理会左右关系不经过大脑直接作问题少女状问很白的问题:“‘移码和真值的关系’是E=27(或210)+X,那X=E-27(或210),在怎么着里面数该是128(或1024),咋是127(或1023)?” 当E=M=全0 E(移码)=全0,对应真值-128 M(补码)=全0,对应真值0 E=M=全0,真值X=0-128=0 结合符号位S 为0或1分正零和负零 当E=全1,M=全0 E(移码)=全1,对应真值+127 M(补码)=全0,对应真值0 E=全1,M=全0,真值X=0127=∞ 结合符号位S 为0或1分+∞和-∞ 要除去表示零和无穷大这2种特殊情况 指数偏移值不选128(10000000),而选127(01111111) 对IEEE32位规格化浮点数 8位移码(隐含1位符号位)原本表示范围是-128 →+127 (除去全1(+127)全0(-128)剩下-127 →+126 ???) 实际可用指数值(即阶码真值)e范围是-126→+127 加上偏移值后,阶码E的范围变为1→254 以10的幂表示,绝对值的范围是10-38→1038 假设由S,E,M三个域组成的一个32位二进制字所表示的非零规格化浮点数x,真值表示为:x=(-1)s×(1.M)×2E-128 它所表示的规格化的最大正数、最小正数、最大负数、最小负数是多少? 第二节 1、什么是IEEE754标准 用来规范化浮点数,其格式是

计算机的工作原理

第周星期第节年月日

教学过程 图2-5.1 计算机内的五大部件 二、计算机指令与程序 计算机根据人们预先设计的一串指令来自动地进行数据的计算和信息的加工处理,这一串指令就称为程序。 一个指令规定计算机执行一个基本操作。一个程序规定计算机完成一个完整的任务。由于计算机只能识别二进制数,所以指令也必须用二进制代码表示,这就是机器指令。 为了便于记忆和使用,人们发明了用英文字母和符号代表指令的方法,这就是汇编指令和汇编语言。后来计算机专家又发明了与我们日常使用习惯很接近的“高级”语言,常用的高级语言有:Pascal、C、Java等。汇编语言和高级语言都要由专门的程序“翻译”成机器指令,计算机才能识别并执行。例如,加法操作对应的指令: 机器指令汇编指令高级语言 11000110 ADD C,A C=C+A 【想一想】 我们在五年级学过的LOGO是高级语言吗?为什么?LOGO中是如何做加法的? 三、计算机工作原理 计算机的基本工作原理是存贮程序和程序控制。存储程序是指人们必须事先把计算机程序及相关的数据,输入并存储在计算机的存储器中。程序控制是指计算机能自动地逐一取出程序中的指令,加以分析并执行规定的操作。这就是美籍匈牙利数学家冯.诺依曼在20世纪40年代计算机诞生的初期提出来的“程序存储”原理。

【知识拓展】计算机之父--冯·诺依曼 1945年6月,冯.诺依曼提出了在数字计算机内部的存储 器中存放程序的概念,被称为“冯.诺依曼结构”,按这一结构 建造的计算机称为存储程序计算机(又称为通用计算机)。冯. 诺依曼计算机主要由运算器、控制器、存储器和输入输出设备 组成,它的的特点是:程序以二进制代码的形式存放在存储器中;所有的指令都是由操作码和地址码组成;指令在其存储过程中按照执行的顺序;以运算器和控制器作为计算机结构的中心等。直到目前,计算机仍是按照这个原理进行工作和加工处理信息的。 下面就以一个汇编语言程序在计算机中的运行过程来说明计算机的工作原理。例如,要求计算机实现将13和15相加,结果28放在CPU的累加器中。具体步骤如下: 1、编写程序 用3条汇编指令,就可以实现两个数相加。 LD A,DH ;将16进制数D(即13)送累加器A ADD A,FH ;将16进制数F(即15)与累加器中的D相加 HALT ;暂停 想一想,执行了以上3条指令后,累加器A中存储的数是多少? 2、输入程序 将以上程序输入到计算机的内存中,并由汇编程序“翻译”成目标程序(机器指令)。见表2-5.1。 源程序目标程序说明 LD A,DH 00111110;表示“取数”操作 00001101;表示“操作数”13 ADD A,FH 11000110;表示“累加”操作 00001111;表示“操作数”15 HALT 01110110;表示“暂停”操作 表2-5.1

计算机中数值的表示

数值型数据由数字组成,表示数量,用于算术操作中。 3.5.1 定点数和浮点数的概念 在计算机中,数值型的数据有两种表示方法,一种叫做定点数,另一种叫做浮点数。 所谓定点数,就是在计算机中所有数的小数点位置固定不变。定点数有两种:定点小数和定点整数。定点小数将小数点固定在最高数据位的左边,因此,它只能表示小于1的纯小数。定点整数将小数点固定在最低数据位的右边,因此定点整数表示的也只是纯整数。由此可见,定点数表示数的范围较小。 为了扩大计算机中数值数据的表示范围,我们将12.34表示为0.1234×102,其中0.1234叫做尾数,10叫做基数,可以在计算机内固定下来。2叫做阶码,若阶码的大小发生变化,则意味着实际数据小数点的移动,我们把这种数据叫做浮点数。由于基数在计算机中固定不变,因此,我们可以用两个定点数分别表示尾数和阶码,从而表示这个浮点数。其中,尾数用定点小数表示,阶码用定点整数表示。 在计算机中,无论是定点数还是浮点数,都有正负之分。在表示数据时,专门有1位或2位表示符号,对单符号位来讲,通常用“1”表示负号;用“0”表示正号。对双符号位而言,则用“11”表示负号;“00”表示正号。通常情况下,符号位都处于数据的最高位。 3.5.2 定点数的表示 一个定点数,在计算机中可用不同的码制来表示,常用的码制有原码、反码和补码三种。不论用什么码制来表示,数据本身的值并不发生变化,数据本身所代表的值叫做真值。下面,我们就来讨论这三种码制的表示方法。 1. 原码 原码的表示方法为:如果真值是正数,则最高位为0,其它位保持不变;如果真值是负数,则最高位为1,其它位保持不变。 【例1】写出13和–13的原码(取8位码长) 解:因为13=(1101)2,所以13的原码是00001101,-13的原码是10001101。 采用原码,优点是转换非常简单,只要根据正负号将最高位置0或1即可。但原码表示在进行加减运算时很不方便,符号位不能参与运算,并且0的原码有两种表示方法:+0的原码是00000000,-0的原码是10000000。 2. 反码 反码的表示方法为:如果真值是正数,则最高位为0,其它位保持不变;如果真值是负数,则最高位为1,其它位按位求反。 【例2】写出13和–13的反码(取8位码长) 解:因为13=(1101)2,所以13的反码是00001101,-13的反码是11110010。 反码跟原码相比较,符号位虽然可以作为数值参与运算,但计算完后,仍需要根据符号位进行调整。另外0的反码同样也有两种表示方法:+0的反码是00000000,-0的反码是11111111。为了克服原码和反码的上述缺点,人们又引进了补码表示法。补码的作用在于能把减法运算化成加法运算,现代计算机中一般采用补码来表示定点数。 3. 补码 补码的表示方法为:若真值是正数,则最高位为0,其它位保持不变;若真值是负数,则最高位为1,其它位按位求反后再加1。 【例3】写出13和–13的补码(取8位码长) 解:因为13=(1101)2,所以13的补码是00001101,-13的补码是11110011。

2.浮点数的存储原理

问题:long和float类型都是四个字节,为什么存储数值的范围相差极大? 原因:因为两者的存储原理时不同的。 浮点数的存储原理 作者: jillzhang 联系方式:jillzhang@https://www.doczj.com/doc/0415925472.html, 本文为原创,转载请保留出处以及作者,谢谢 C语言和C#语言中,对于浮点类型的数据采用单精度类型(float)和双精度类型(double)来存储,float数据占用32bit,double数据占用64bit,我们在声明一个变量float f= 2.25f的时候,是如何分配内存的呢?如果胡乱分配,那世界岂不是乱套了么,其实不论是float还是double在存储方式上都是遵从IEEE的规范的,float遵从的是IEEE R32.24 ,而double 遵从的是R64.53。 无论是单精度还是双精度在存储中都分为三个部分: 1.符号位(Sign) : 0代表正,1代表为负 2.指数位(Exponent):用于存储科学计数法中的指数数据,并且采用移位存储 3.尾数部分(Mantissa):尾数部分 其中float的存储方式如下图所示: 而双精度的存储方式为:

R32.24和R64.53的存储方式都是用科学计数法来存储数据的,比如8.25用十进制的科学计数法表示就为:8.25*,而120.5可以表示为:1.205*,这些小学的知识就不用多说了吧。而我们傻蛋计算机根本不认识十进制的数据,他只认识0,1,所以在计算机存储中,首先要将上面的数更改为二进制的科学计数法表示,8.25用二进制表示可表示为1000.01,我靠,不会连这都不会转换吧?那我估计要没辙了。120.5用二进制表示为:1110110.1用二进制的科学计数法表示1000.01可以表示为1.0001* ,1110110.1可以表示为1.1101101*,任何一个数都的科学计数法表示都为1.xxx*,尾数部分就可以表示为xxxx,第一位都是1嘛,干嘛还要表示呀?可以将小数点前面的1省略,所以23bit的尾数部分,可以表示的精度却变成了24bit,道理就是在这里,那24bit能精确到小数点后几位呢,我们知道9的二进制表示为1001,所以4bit能精确十进制中的1位小数点,24bit就能使float能精确到小数点后6位,而对于指数部分,因为指数可正可负,8位的指数位能表示的指数范围就应该为:-127-128了,所以指数部分的存储采用移位存储,存储的数据为元数据+127,下面就看看8.25和120.5在内存中真正的存储方式。 首先看下8.25,用二进制的科学计数法表示为:1.0001* 按照上面的存储方式,符号位为:0,表示为正,指数位为:3+127=130 ,位数部分为,故8.25的存储方式如下图所示: 而单精度浮点数120.5的存储方式如下图所示:

有关浮点数在内存中的存储

有关浮点数在内存中的存储 最近想看一下C中float和double型数据在内存中是如何表示的,找到了如下一些东东,与大家分享一下 c语言中FLOAT 是如何表示的?尾数,阶码是如何在32位上安排的,即哪几位是尾数,哪几位是阶码,那一位是符号位。听说与CPU有关,是真的吗? 在C++里,实数(float)是用四个字节即三十二位二进制位来存储的。其中有1位符号位,8位指数位和23位有效数字位。实际上有效数字位是24位,因为第一位有效数字总是“1”,不必存储。 有效数字位是一个二进制纯小数。8位指数位中第一位是符号位,这符号位和一般的符号位不同,它用“1”代表正,用”0“代表负。整个实数的符号位用“1”代表负,“0”代表正。 在这存储实数的四个字节中,将最高地址字节的最高位编号为31,最低地址字节的最低位编号为0,则实数各个部分在这32个二进制位中的分布是这样的:31位是实数符号位,30位是指数符号位,29---23是指数位,22---0位是有效数字位。注意第一位有效数字是不出现在内存中的,它总是“1”。 将一个实数转化为C++实数存储格式的步骤为: (1)先将这个实数的绝对值化为二进制格式,注意实数的整数部分和小数部分化为二进制的方法是不同的。 (2)将这个二进制格式实数的小数点左移或右移n位,直到小数点移动到第一个有效数字的右边。 (3)从小数点右边第一位开始数出二十三位数字放入第22到第0位。 (4)如果实数是正的,则在第31位放入“0”,否则放入“1”。 (5)如果n 是左移得到的,说明指数是正的,第30位放入“1”。如果n是右移得到的或n=0,则第30位放入“0”。 (6)如果n是左移得到的,则将n减去一然后化为二进制,并在左边加“0”补足七位,放入第29到第23位。如果n是右移得到的或n=0,则将n化为二进制后在左边加“0”补足七位,再各位求反,再放入第29到第23位。 将一个计算机里存储的实数格式转化为通常的十进制的格式的方法如下: (1)将第22位到第0位的二进制数写出来,在最左边补一位“1”,得到二十四位有效数字。将小数点点在最左边那个“1”的右边。 (2)取出第29到第23位所表示的值n。当30位是“0”时将n各位求反。当30位是“1”时将n增1。 (3)将小数点左移n位(当30位是“0”时)或右移n位(当30位是“1”时),得到一个二进制表示的实数。 (4)将这个二进制实数化为十进制,并根据第31位是“0”还是“1”加上正号或负号即可。

浮点数的表示和基本运算

浮点数的表示和基本运算 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长度来反映无限的实数集合,因此大多数情况下都是一个近似值。同时,对于浮点数的运算还同时伴有误差扩散现象。特定精度下看似

浮点数在内存中的存储方式

浮点数在内存中的存储方式 任何数据在内存中都是以二进制的形式存储的,例如一个short型数据1156,其二进制表示形式为00000100 10000100。则在Intel CPU架构的系统中,存放方式 为10000100(低地址单元) 00000100(高地址单元),因为Intel CPU的架构是小端模式。但是对于浮点数在内存是如何存储的?目前所有的C/C++编译器都是采用IEEE所制定的标准浮点格式,即二进制科学表示法。 在二进制科学表示法中,S=M*2^N 主要由三部分构成:符号位+阶码(N)+尾数(M)。对于float型数据,其二进制有32位,其中符号位1位,阶码8位,尾数23位;对于double型数据,其二进制为64位,符号位1位,阶码11位,尾数52位。 31 30-23 22-0 float 符号位阶码尾数 63 62-52 51-0 double 符号位阶码尾数 符号位:0表示正,1表示负 阶码:这里阶码采用移码表示,对于float型数据其规定偏置量为127,阶码有正有负,对于8位二进制,则其表示范围为-128-127,double型规定为1023,其表示范围为 -1024-1023。比如对于float型数据,若阶码的真实值为2,则加上127后为129,其阶码表示形式为10000010 尾数:有效数字位,即部分二进制位(小数点后面的二进制位),因为规定M的整数部分恒为1,所以这个1就不进行存储了。

下面举例说明: float型数据125.5转换为标准浮点格式 125二进制表示形式为1111101,小数部分表示为二进制为1,则125.5二进制表示为1111101.1,由于规定尾数的整数部分恒为1,则表示为1.1111011*2^6,阶码为6,加上127为133,则表示为10000101,而对于尾数将整数部分1去掉,为1111011,在其后面补0使其位数达到23位,则为11110110000000000000000 则其二进制表示形式为 0 10000101 11110110000000000000000,则在内存中存放方式为: 00000000 低地址 00000000 11111011 01000010 高地址 而反过来若要根据二进制形式求算浮点数如0 10000101 11110110000000000000000 由于符号为为0,则为正数。阶码为133-127=6,尾数为11110110000000000000000,则其真实尾数为1.1111011。所以其大小为 1.1111011*2^6,将小数点右移6位,得到1111101.1,而1111101的十进制为125,0.1的十进制为1*2^(-1)=0.5,所以其大小为125.5。 同理若将float型数据0.5转换为二进制形式

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

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

计算机采用存储程序原理的提出者是()

1.计算机采用“存储程序”原理的提出者是() A.乔布斯B.冯·诺依曼C.比尔·盖茨D.马云 2.下列表示的存储容量中,最大的是() A.1GB B.1MB C.512B D.512KB 3.下列数据中可以表示二进制数的是() A.456 B.AF9 C.986 D.1011 4.计算机软件可以分为() A.系统软件和通用软件B.应用软件和系统软件 C.操作系统和网络软件D.编译程序和常用工具软件 5.下列对任务栏操作表述正确的是() A.能改变大小不能移动B.不能改变大学不能移动 C.能改变大小也能移动D.不能改变大小也不能移动 6.在Windows XP 窗口菜单命令项中,若选项呈灰色,这意味着() A.该命令项当前暂时不可用B.命令项除了差错 C.该命令项可以使用,变灰色是由于是故障所致 D.该命令项并不存在,以后也无法使用 7.在Windows XP资源管理器中显示文件的修改日期,可选择“查看”菜单中()A.缩略图B.图标C.列表D.详细信息 8.窗口和对话框的区别是 A.对话框不能移动,也不能改变大小 B.两者都能改变大小,但对话框不能移动 C.两者都能移动,但对话框不能改变大小 D.两者都能移动和改变大小 9.在Word2003的文档编辑状态下,文档的名称显示在() A.工具栏B.菜单栏C.标题栏D.状态栏 10.在Word2003的文档编辑状态下,删除插入点之后的一个字符,可以按()A.Insert键B.Delete键C.Backspace 键D.Capslock键 11.启动Word2003,系统自动创建新文档的文件名为() A.文件1.doc B.文档1 .doc C.Noname.doc D.UntitleD.doc 12.Word2003默认的视图方式是() A.页面视图B.Web版式视图C.普通视图D.大纲视图 13.将当前编辑的Word2003文档转存为其它格式的文件时,应使用“文件”菜单中的()命令 A.保存B.页面设置C.属性D.另存为 14.在Excel2003中,一般文件的默认保存类型为() A..doc B..bmp C..xls D..ppt 15.在Excel2003中,下来属于默认单元格地址的是() A.E6 B.6E C.6 D.E 16.在Excel2003的单元格中输入3/5,则该单元格默认的数据类型是()A.文本型B.数值型C.日期型D.逻辑型 17.在Excel2003中进行操作时,若某单元格中出现“######”的内容时,含义是()A.在公式单元格引用不再有效 B.单元格中的数字太大 C.计算结果太长超过了单元格宽度

浮点数表示方法与运算

在计算机系统的发展过程中,曾经提出过多种方法表达实数,典型的比如定点数。在定点数表达方式中,小数点位置固定,而计算机字长有限,所以定点数无法表达很大和很小的实数。最终,计算机科学发展出了表达范围更大的表达方式——浮点数,浮点数也是对实数的一种近似表达。 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.浮点数的表示范围 求浮点数的表示范围,实质是求浮点数所能表示的最小负数、最大负数、最小正数和最大正数。

浮点数在计算机内存中的存储格式

浮点数在计算机内存中的存储格式 对于浮点类型的数据采用单精度类型(float)和双精度类型(double)来存储,float数据占用 32bit,double数据占用 64bit,我们在声明一个变量float f = 2.25f的时候,是如何分配内存的呢?其实不论是float类型还是double类型,在计算机内存中的存储方式都是遵从IEEE的规范的,float 遵从的是IEEE R32.24 ,而double 遵从的是R64.53。 无论是单精度还是双精度,在内存存储中都分为3个部分: 1) 符号位(Sign):0代表正,1代表为负; 2) 指数位(Exponent):用于存储科学计数法中的指数数据,并且采用移位存储; 3) 尾数部分(Mantissa):尾数部分; 其中float的存储方式如下图所示: 而双精度的存储方式为: R32.24和R64.53的存储方式都是用科学计数法来存储数据的,比如8.25用十 进制的科学计数法表示就为:8.25*,而120.5可以表示为:1.205*。而我 们傻蛋计算机根本不认识十进制的数据,它只认识0和1,所以在计算机内存中,首先要将上面的数更改为二进制的科学计数法表示,8.25用二进制表示可表示为1000.01,120.5用二进制表示为:1110110.1。用二进制的科学计数法 表示1000.01可以表示为1.00001*,1110110.1可以表示为 1.1101101*,任何一个数的科学计数法表示都为 1.xxx*, 尾数部分就可以表示为xxxx,第一

位都是1嘛,干嘛还要表示呀?可以将小数点前面的1省略,所以23bit的尾数部分,可以表示的精度却变成了 24bit,道理就是在这里,那24bit能精确到小数点后几位呢,我们知道9的二进制表示为1001,所以4bit能精确十进制中的1位小数点,24bit就能使float能精确到小数点后6位,而对于指数部分,因为指数可正可负,8位的指数位能表示的指数范围就应该为:-127-128了,所以指数部分的存储采用移位存储,存储的数据为元数据+127。 下面就看看8.25和120.5在内存中真正的存储方式: 首先看下8.25,用二进制的科学计数法表示为:1.0001* 按照上面的存储方式,符号位为0,表示为正;指数位为3+127=130,位数部分为 1.00001,故8.25的存储方式如下: 0xbffff380: 01000001000001000000000000000000 分解如下:0--10000010--00001000000000000000000 符号位为0,指数部分为10000010,位数部分为 00001000000000000000000 同理,120.5在内存中的存储格式如下: 0xbffff384: 01000010111100010000000000000000 分解如下:0--10000101--11100010000000000000000 那么如果给出内存中一段数据,并且告诉你是单精度存储的话,你如何知道该数据的十进制数值呢?其实就是对上面的反推过程,比如给出如下内存数据: 01000001001000100000000000000000 第一步:符号位为0,表示是正数; 第二步:指数位为10000010,换算成十进制为130,所以指数为130-127=3; 第三步:尾数位为01000100000000000000000,换算成十进制为 (1+1/4+1/64); 所以相应的十进制数值为:2^3*(1+1/4+1/64)=8+2+1/8=10.125 再看一个例子,观察其输出: 02 { 03 float f1 = 2.2; 04 float f2 = 2.25;

浮点数1

浮点数在计算机中用以近似表示任意某个实数。具体的说,这个实数由一个整数或定点数(即尾数)乘以某个基数(计算机中通常是2)的整数次幂得到,这种表示方法类似于基数为10的科学记数法。 浮点计算是指浮点数参与的运算,这种运算通常伴随着因为无法精确表示而进行的近似或舍入。 一个浮点数a由两个数m和e来表示:a = m × be。在任意一个这样的系统中,我们选择一个基数b(记数系统的基)和精度p(即使用多少位来存储)。m(即尾数)是形如±d.ddd...ddd的p位数(每一位是一个介于0到b-1之间的整数,包括0和b-1)。如果m的第一位是非0整数,m称作规格化的。有一些描述使用一个单独的符号位(s 代表+或者-)来表示正负,这样m必须是正的。e是指数。 这种设计可以在某个固定长度的存储空间内表示定点数无法表示的更大范围的数。 例如,一个指数范围为±4的4位十进制浮点数可以用来表示43210,4.321或0.0004321,但是没有足够的精度来表示432.123和43212.3(必须近似为432.1和43210)。当然,实际使用的位数通常远大于4。 此外,浮点数表示法通常还包括一些特别的数值:+∞和?∞(正负无穷大)以及NaN('Not a Number')。无穷大用于数太大而无法表示的时候,NaN则指示非法操作或者无法定义的结果。 大部份计算机采用二进制(b=2)的表示方法。位(bit)是衡量浮点数所需存储空间的单位,通常为32位或64位,分别被叫作单精度和双精度。有一些计算机提供更大的浮点数,例如英特尔公司的浮点运算单元Intel8087协处理器(以及其被集成进x86处理器中的后代产品)提供80位长的浮点数,用于存储浮点运算的中间结果。还有一些系统提供128位的浮点数 浮点数的表示 在实际应用中,往往会使用实数,例如下面的一些十进制实数: 179.2356=0.1792356x10^3 0.000000001=0.1x10^8 3155760000=0.215576x10^6 很明显,上述第一个数既有整数也有小数,不能用定点数格式化直接表示,后两个数则可能超出了定点数的表示范围,所以计算机引入了类似与科学表示法来标示实数。 (1)典型的浮点数格式 在机器中,典型的浮点数格式如图所示 浮点数代码由两部分组成:阶码E和尾数M。浮点数真值为: N=+/-(R^E)xM R是阶码的底。在机器中一般规定R为2,4,8或16,与尾数的基数相同。例如尾数为二进制,则R也为2。同一种机器的R值是固定不变的,所以不需要在浮点数代码中表示出来,他是隐含约定的。因此,机器中的浮点数只需表示出阶码和尾数部分。 E是阶码,即指数值,为带符号整数,常用移码或补码表示。 M是尾数,通常是纯小数,常用原码或补码表示。

数的定点表示和浮点表示

计算机处理的数值数据多数带有小数,小数点在计算机中通常有两种表示方法,一种是约定所有数值数据的小数点隐含在某一个固定位置上,称为定点表示法,简称定点数;另一种是小数点位置可以浮动,称为浮点表示法,简称浮点数。 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处理,称为下溢;大于定点数能表示的最大值时,计算机将无法表示,称为上溢,上溢和下溢统称为溢出。 计算机采用定点数表示时,对于既有整数又有小数的原始数据,需要设定一个比例因子,数据按其缩小成定点小数或扩大成定点整数再参加运算,运算结果,根据比例因子,还原

计算机组成原理-浮点数表述范围

以32位的浮点数为例 浮点数有一般的格式和IEEE754的格式两种。 一般的格式符合2进制数机器码(包括定点整数和定点小数)的规定规则 IEEE表示则是为了实现上的方便,做了一些约定的格式改变。 先说说问题的描述方式: 1、一个32位的二进制数来表示的浮点数。都是由阶和尾数两部分组成。阶和尾数都带有一位符号位,分别称为阶符和数符。 2、从图例表示可以有两种方式: (1)一种是阶和尾数分别带着符号位表示,依次为阶符(ES)、阶(E)、数符(MS)和尾数(M) (2)另一种是把数符提前到整个浮点数的最前面,表示整个浮点数的符号位,标记为S。 这两种表示方式是一致的。前者比较直接明了地分隔成“阶”(包括阶符和阶)和“尾数”(包括数符和尾数)两部分;后者则是为了便于软件移植的格式。 比较流行的教材的新版本都倾向于使用后一种表示方式。 因此,下面开始,我们都采用后一种方式叙述。

3、从真值的表示方式来说有多种不同的情况 符号位统一都是:(-1)s 一般表示法的阶:e=E-128(完全符合机器码的移码规则)。该部分在真值中表示为2E-128,注意,E为带符号位的阶所表示的无符号数大小。比如8位阶(包含一位符号位),以移码表示,以11111111为例,E=255,而e=127,在真值中表示为2127。 IEEE表示法的阶:e=E-127(是IEEE的一个约定,不符合机器码的移码规则)。该部分在真值中表示为2E-127,注意,E为带符号位的阶所表示的无符号数大小。比如8位阶(包含一位符号位),以移码表示,以11111111为例,E=255,而e=128,在真值中表示为2128。 一般表示法的尾数:M,该部分在真值中以M表示,规划化处理是使得M 的最高位和符号位不同值,或者说用异或判断结果为1(其本质在于使得该数值的绝对值≥0.5)。 IEEE表示法的尾数:1.M,该部分在真值中以1.M表示,因为IEEE表示方式本来就是一种标准格式,所以不存在不是规格化的数。其中尾数域的小数点前约定的那个1不予存储,默认其隐藏在小数点的左边。 因此,一般表示法和IEEE表示法就可以组成四种组合真值表示。 (1)纯一般表示法(阶和尾数都是一般表示法)真值表示为:(-1)s?M?2E-128 (2)纯IEEE表示法(阶和尾数都是IEEE表示法)真值表示为:(-1)s?(1.M)?2E-127 (3)混合表示法A(阶位一般表示法,尾数都是IEEE表示法)真值表示为:(-1)s?(1.M)?2E-128,课本例9就是用了这种混合表示法。 (2) 混合表示法B(阶位IEEE表示法,尾数都是一般表示法)真值表示为:(-1)s?M?2E-127 注意:如果题目没有做明确描述。就默认其采用的是“纯一般表示法”。 弄清楚问题的描述方式后,我们来看看各种表示方法的表数范围。 分别从一般表示法的阶和尾数,IEEE的阶和尾数,4个组成部分来分析。

相关主题
文本预览
相关文档 最新文档