1、0 请问 float型数据在 mega128中是如何存储的?一个float型数据,占用连续四个字节地址,用iccavr编译,是按照什么规则来编译然后存储的呢?我试了试,好像不像是网上说的按照ieee745标准啊。郁闷了。我又弄明白了,原来是我自己搞错了,iccavr也是用得那个统一的ieee745标准。顺便把我看得资料给大家分享一下吧,万一以后大家可能用的着呢:)以下为引用:自学者疑难之一,实型数在计算机中的存储方式 Red_Fox笔于2006-12-12 17:13 由于关于实型数介绍的资料很少, 同时介绍的资料描述得都很简短,各种专业教程中都是 简单带过,没有具体的讲解.这样的情况下只好边
2、参考资料边进行逆向分析, 经过分析验证后 得出以下结论并整理成文档。虽然编写程序时可以不关心它的存储方式,编译器可以自动进 行转换,但在许多情况下了解它的存储方式却是个关键。以下的分析目的都旨在于: “知其然,知其所以然“. 读懂本文所需的前提是了解补码 实型数的表示,根据IEEE(14)标准分析如下 一.先将浮点数转换为二进制数并进行规格化. 1.转换为二进制并规格化一个数时将其调整为大于等于1而小于2,存储时隐含掉整数部分只保留尾数; 如(这部分可以只了解下): 10进制数12 10进制转2 进制为: 12 = 1100 ; 1100 规格化后为 : 1.1 * 23这样一个表达式(等同于
3、对 1.1左移位3次),23 表示2的3 次方. 12 : 是正数既符号位为0. 存到符号字段中 23: 3就是阶码. 存到阶码字段中 1.1: .1是尾数 . 存到尾数字段中 “1.1“中的整数“1“不需要存储,只存储尾数 如果是0.111这样的二进制数码则调整为 1.11 * 2-1 . 即阶码 = -1; 尾数 = 11; 数值“12“存储为float的结果是: (数据结构图) 为了对齐行列 ,各表示: A:符号; B:移码阶; C:尾数. | A | B | C | | 0 | 10000010 | 1000000 00000000 00000000 | 关于B:移码阶部分一定会让人比
4、较迷惑,这里可以先不用管,这部分重点放在第二大段中介绍. 2.浮点数中尾数的二进制转换及规格化 浮点数尾数部分。 通常的转换方式可以转换得出(如除2 求余法), 但进一步整理下思路可以使后文 更易于理解. 以10 进制数 :27.4375为例,它们的关系是( 书上直接抄来的例子 ): A冥 B权 C数码 D数值(10进制) A 24 23 22 21 20 2-1 2-2 2-3 2-4 B 16 8 4 2 1 0.5 0.25 0.125 0.0625 C 1 1 0 1 1 . 0 1 1 1 11011.0111(2进制) D 16 + 8 + 0 + 2 + 1 + 0 + 0.25
5、 + 0.125 + 0.0625 = 27.4375 二.在机器中的存储方式 以float来做分析,存储中位的顺序由高到低描述是: float 符号位1bit;阶码位8bit;尾数23bit.共计32bit 即 4 byte长度. 符号位: 标识数的正负符号,1 表示(-) 阶码部分: 由于是8bit;阶为2 。因此2的8次方 = 256个描述信息 规范中,数的表示法有些特别,使用偏移量方式计算。 表示方法为: 阶的偏移量 E_Disp = 127 = (256/2 -1) 阶码为E表示为 存储方式 e = E + E_Disp 所以,使用存储方式 e来计算时需要在之上减去E_Disp, 即
6、: E = e - E_Disp 此阶码的特点: 这种表示法形式实为补码,但这种表示法不同于普通补码 .它使用偏移量计算, 偏移量即补码,同普通补码的区别是末位不进行加1修正. 这种表示法中因为0不应该存在负数,而又没有普通补码表示法的修正,所以 存储0时全存为 0 同时这样的方法带来一个额外的空间,原因是表示 (+-)127 的情况下范围 为:127*2 = 254 实际可用范围为256,0占用1个范围,(+-)127占用254的范围,这 样就是:256-(127*2 + 1) = 1。但是这个描述信息并没有被浪费,它在IEEE(14) 作者: 220.172.104.*2007-2-1 1
7、6:17 回复此发言 2 自学者疑难之一 ,实型数在计算机中的存储方式 规范中用于表示无穷大即 : 。这种方式下无穷表示为:阶码部分全为1,尾码部分 全为0,符号位标识 (+- ). 综合说明: 1.阶码存储为 : 阶码 + 偏移量127; 2.被存储的数值为 0时不进行任何形式的转换,将其全存为0,符号位唯一确定为0; 3.被存储的数值为 +-无穷时阶码位全存为1,尾数位全存为0,符号位表示+-; 尾数部分: 可以倒回去看第一大段的例子. 额外的说明与思考: 这种形式是一种科学标识法其起源很早, 但鄙人才疏学浅无从追寻根源 ,这种形 式只为此方式的一种。进一步了解该方法是将来解决许多问题的捷
8、径写出能解决特殊 问题的算法的基础。后面紧接着就更深入的分析下去。 已提到这是一种科学标识方法, 它并不局限于IEEE标准,它的实际形式是: |符号位 |阶码符号位|阶码|尾数| 这个形式在 “阶码“和“尾数“ 的长度上并没有数理上的限制,特殊场合里可以进行 自定义.这里不是说在编写程序的时候可以不理会IEEE的标准了, 那取决于当前的开发 环境,在机器上使用标准开发环境时是必须严格遵守IEEE标准的, 这是一个规范,否则就 要放弃环境的默认处理,改为自己用算法来处理数的转换及计算. 也就是说如果使用了自己定义的数据, 那如cpu 的 ADD 指令等不能再直接使用来进 行对它的处理了,因为计算
9、机的数据格式是遵循IEEE标准的 .这段话看起来有点让人觉得 废话,但我觉得有必要强调一下,以免误与他人. 而,这就是关于这一小段“额外“存在的理由.根据这个实际形式可以定义自己的浮点 数,用它来实现超大体积的浮点数、定点数的存储及计算,也或是超小体积. 继续就IEEE的标准做进一步说明与分析 : 在前一小节的分析中没有关于“ 阶码的符号位“的描述. 然,偏移量为127 ; 127 = 1111111 (占用7bit). 偏移量 + 阶码的结果为正数会达到8bit宽, 负数则只会小于 8bit宽,因为阶码以补码 形式存储,那获得阶码必有一个计算过程即减去E_Disp,结果就是正数或负数,所以实际上 已经不需要阶码正负符号位或可以说成是:1表示正数;0表示负数. 到这里,我补充进来的目的应能让人很清楚了.这只是一种储存方式,必要的时候可 以不受限制的搬来灵活运用, 自定义数据结构. double型: double 8byte 符号位1bit;阶码位11bit;尾数52bit 除了偏移量的不同即: 阶的偏移量 E_Disp = (2048/2 -1),其它的相同.