已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
浮点数显示 C51 里用 4 字节存储一个浮点数 格式遵循 IEEE 754 标准 详见 c51 pdf 第 179 页说明 一个浮点数用两个部分表示 尾数和 2 的幂 尾数代表浮点上的实际二进制数 2 的幂代 表指数 指数的保存形式是一个 0 到 255 的 8 位值 指数的实际值是保存值 0 到 255 减去 127 一个范围在 127 到 128 之间的值 尾数是一个 24 位值 代表大约 7 个十进制数 最高 位 MSB 通常是 1 因此不保存 一个符号位表示浮点数是正或负 浮点数保存的字节格式 如下 地址 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 作为一个十六进制数 0 xC1480000 保存在存储区中 这个值如下 地址 0 1 2 3 内容 0 xC1 0 x48 0 x00 0 x00 浮点数和十六进制等效保存值之间的转换相当简单 下面的例子说明上面的值 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 这个 1 在浮点数的保存中经常省略 加上一个 1 和小 数 点到尾数的开头 得到尾数值如下 1 10010000000000000000000 接着 根据指数调整尾数 一个负的指数向左移动小数点 一个正的指数向右移动小数点 因为 指数是 3 尾数调整如下 1100 10000000000000000000 结果是一个二进制浮点数 小数点左边的二进制数代表所处位置的 2 的幂 例如 1100 表 示 1 2 3 1 2 2 0 2 1 0 2 0 12 小数点的右边也代表所处位置的 2 的幂 只是幂是负的 例如 100 表示 1 2 1 0 2 2 0 2 2 0 5 这些值的和是 12 5 因为设置的符号位表示这数是负的 因此十六进制值 0 xC1480000 表 示 12 5 浮点数错误信息 8051 没有包含捕获浮点数错误的中断向量 因此 你的软件必须正确响应这些错误情 况 除了正常的浮点数值 还包含二进制错误值 这些值被定义为 IEEE 标准的一部分并用 在 正常浮点数操作过程中发生错误的时候 你的代码应该在每一次浮点操作完成后检查可能 出 现的错误 名称 值 含义 NaN 0 xFFFFFFF 不是一个数 INF 0 x7F80000 正无穷 正溢出 INF 0 xFF80000 负无穷 负溢出 你可以使用如下的联合体 union 存储浮点数 union f float f 浮点值 unsigned long ul 无符号长整数 这个 union 包含一个 float 和一个 unsigned long 以便执行浮点数学运算并响应 IEEE 错误 状态 以上是 KEIL 在线帮助的中译文 下面我们讨论如何显示浮点数 尾数为 24bit 最高可表达的整数值为 2 24 1 16777215 也就是说 小于等于 16777215 的整数可以被精确显示 这决定了十进制浮点数的有效位数为 7 位 10 7 16777215 10 8 10 的 7 次方以内的数小于 16777215 可以精确表示 使用科学记 数法时 整数部分占 1 位 所以小数部分最大占 7 1 6 位 即最大有 6 位十进制精度 长整形数和浮点数都占 4 字节 但表示范围差别很大 浮点数的范围为 1 175494E 38 到 3 402823E 38 无符号长整形数范围为 0 到 4294967295 显示浮点数要用到长整形数 保存数据 可他们范围差这么多 怎么办呢 仔细观察十进制浮点数的显示 有一个尾数和一个阶码 由上面论证可知 32 位 IEEE 754 浮点数最大有效数字为 7 位十进制数 超出此范围的数字有截断误差 不必理会 因 此 浮点数尾数能够放在长整形数里保存 阶码为 38 到 38 一个 char 型变量就可以保存 综上所述 以 10 7 的最大跨度为窗口 小于 10 7 也可以 如 10 100 10000 等 但决 不能大于它 那样会超出精度范围 定位浮点数的量级 然后取出 7 位尾数的整数值存于 长 整形数里 再调整阶码 就可以精确显示此浮点数 量级尺度如下 38 35 28 21 14 7 0 7 14 21 28 35 38 请严格按照 KEIL 手册给出的浮点数范围显示 因为数值空间没有完全使用 有些值用 于错误指示和表示正负无穷 小于 1 175494E 38 的数仍可以显示一些 但最好不用 以免 出错 我采用直接判断的方法 剔除此种情况 在计算机里结合律不成立 a b c a b c 原则是先让计算结果值动态范围小的两个 数运算 请注意程序里的写法 注 1E38 b 1E6 不要写成 1E44 b 因为无法在 32 位浮点数里保存 1E44 切记 计算机使用二进制数计算 能有效利用电子器件高速开关的特性 而人习惯于十进制数 表示 二进制和十进制没有方便的转换方法 只能通过大量计算实现 浮点数的十进制科 学记数法显示尤其需要大量的运算 可见 显示一个浮点数要经过若干次浮点运算 没有 必要就不要显示 否则 花在显示上的时间比计算的耗时都要多得多 源程序 void DispF float f reentrant 用科学记数法显示浮点数 在 float 全范围内精确显 示 超出范围给出提示 1 175494E 38 到 3 402823E 38 float tf b unsigned long w tw char i j if f 0 PrintChar f 1 0 f if f1E35 f 10 35 tf f 1E35 b 1000 0 for i 0 j 38 i 4 i j if tf b1E28 10 28 f 10 35 tf f 1E28 b 1E7 for i 0 j 35 i 8 i j if tf b1E21 10 21 f 10 28 tf f 1E21 b 1E7 for i 0 j 28 i 8 i j if tf b1E14 10 14 f 10 21 tf f 1E14 b 1E7 for i 0 j 21 i 8 i j if tf b1E7 10 7 f 10 14 tf f 1E7 b 1E7 for i 0 j 14 i 8 i j if tf b1 1 f 10 7 tf f b 1E7 for i 0 j 7 i 8 i j if tf b1E 7 10 7 f 1 tf f 1E7 b 1E7 for i 0 j 0 i 8 i j if tf b1E 14 10 14 f 10 7 tf f 1E14 b 1E7 for i 0 j 7 i 8 i j if tf b1E 21 10 21 f 10 14 tf f 1E21 b 1E7 for i 0 j 14 i 8 i j if tf b1E 28 10 28 f 10 21 tf f 1E28 b 1E7 for i 0 j 21 i 8 i j if tf b1E 35 10 35 f 10 28 tf f 1E35 b 1E7 for i 0 j 28 i 8 i j if tf b 1 b b 10 0 else break w f 1E35 b 1E6 1E35 b 1E6 PrintW w j else f 10 35 tf f 1E38 b 1000 0 for i 0 j 35 i 4 i j if tf b 1 b b 10 0 else break w f 1E38 b 1E6 1E38 b 1E6 PrintW w j void PrintW unsigned long w char j reentrant 科学记数法 显示十进制尾数和阶 码 char i unsigned long tw b if j38 yyprintf return 此算法不会出现 j 38 的情况 tw w 1000000 PrintChar tw 0 PrintChar w w tw 1000000 b 100000 for i 0 i0 varForLog dblVal varForLog dblVal 1 int nRound DELTA RATE nIntCount return nRound double doublAdd2 double dbl1 double dbl2 COleVariant var dbl1 dbl2 int r1 getRound dbl1 int r2 getRound dbl2 VarRound return var dblVal 做过一些实验 好象是正确的 同理可以实现 doubleSub2 的函数 注意 这里并不用下面五所提的取精度的方式 因为取精度的运算更低效 五 对于乘除法呢 问题有些复杂 先找出一个需要处理的例子 如 2 01 2 01 4 0401 试了一下 不成立 用方法一的 Decimal 方式测试 可以通过 那么方法二呢 再做假设吧 假设 dbl1 有两位小数 dbl2 也有两位小数 按理论 可得出相乘后 最大可能是 2 2 位小数 那么 我们按照 4 位小数 进行 Round 处理 可能会得出正确的结果 实际上 要取一个双精度的 10 进制表达的小数位 我没有找到什么好办法 我能想到的 也就是将数字转为字串 然后查找 后的位数 这样 显然是 非常低效的 这里 我就不再写出代码了 六 比较方法一和方法二 方法二并不高效 并且还有一些不定因素 所以 最好采用方法一来统一处理浮点数的运算 至于效率 实际上最佳方法是从程序的设计着手 将 double 从程序中去除掉 比如在 VC 中 可以用 Variant Decimal 来彻底替换 double
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年时间管理与要事优先:领导者效能提升
- 2026云南文山州西畴县安康医院招聘备考题库及参考答案详解一套
- 2026宁波某国企招聘外包项目工作人员6人备考题库含答案详解(考试直接用)
- 2026广西来宾象州县马坪镇总工会招聘乡镇社会化工会工作者1人备考题库附答案详解(满分必刷)
- 2026山东菏泽市三级医院招聘医护人员15人备考题库完整参考答案详解
- 2026浙江宁波市北仑职业高级中学招聘编外教师1人备考题库附答案详解(a卷)
- 万科物业房屋租赁合同
- 2026甘肃甘南州舟曲县农技推广体系建设与改革项目特聘农技员招聘3人备考题库及一套答案详解
- 2026四川成都市简阳市人力资源社会保障信息中心招聘编外人员4人备考题库附答案详解(模拟题)
- 2026年长春金融高等专科学校公开招聘高层次人才备考题库(1号)补充备考题库及一套完整答案详解
- 2026年广西真龙彩印包装有限公司笔试题及答案
- 河南资本集团笔试题库
- 2026湖北神农架林区公安局招聘辅警22人笔试备考试题及答案解析
- 2026菏泽特殊教育职业学校公开招聘人员(2人)考试模拟试题及答案解析
- 全国数据资源调查报告(2025年)
- 2026年ESG(可持续发展)考试题及答案
- 2026年防治碘缺乏病日宣传课件
- 身骑白马 SSA 三声部合唱谱
- 2026年高级社会工作师押题宝典题库及1套完整答案详解
- 2026年辅警转正考试时事政治试题及答案
- 2025年中国医学科学院基础医学研究所高等学校应届毕业生招聘工作人员6人笔试历年典型考题及考点剖析附带答案详解
评论
0/150
提交评论