
死磕浮点数——浮点数精度之谜
对阶:使小数点对齐,尾数右移或左移。 尾数求和:对齐后的尾数相加。 规格化:将尾数的小数点移到前面,形成1.M形式。 舍入:舍去多余的有效数字,保留精度。 校验判断:检查结果是否溢出或下溢。
发布日期:2021-05-14 08:57:16
浏览次数:19
分类:精选文章
本文共 1138 字,大约阅读时间需要 3 分钟。
浮点数运算中的精度丢失问题是所有编程语言中普遍存在的现象,尤其是在使用32位或64位的浮点数类型时。这种问题的根本原因在于浮点数的二进制表示方式及其运算机制。以下是对该问题的深入分析:
1. 浮点数的二进制表示
浮点数在计算机中以二进制形式存储,主要使用三种表示方法:原码、反码和补码。
- 原码:符号位表示正负,数值位直接存储数字。优点直观,缺点在运算时容易出错。
- 反码:正数与原码相同,负数符号位为1,数值位取反。
- 补码:正数与原码相同,负数反码加1。
IEEE 754标准规定了单精度(32位)和双精度(64位)浮点数的存储方式:
- 单精度:1位符号,8位指数,23位有效数字。
- 双精度:1位符号,11位指数,52位有效数字。
有效数字的表示方式默认第一位为1,后面的位数存储小数部分。指数部分使用偏移值处理负数,以简化运算。
2. 浮点数的加法运算
浮点数加法分为对阶、尾数求和、规格化、舍入和校验判断五个步骤:
3. 实例分析
以0.2和0.4的加法为例:
- 0.2的二进制表示:0 01111101 10011001100110011001100
- 0.4的二进制表示:0 01111101 11001100110011001100100
对阶后:
- 0.2:0 01111101 00110011001100110011001100
- 0.4:0 01111101 11001100110011001100100
尾数求和:
- 00110011001100110011001100 + 11001100110011001100100 = 11111111001110011001100
规格化后:
- 0 01111110 10011001100110011001100
舍入后:
- 1.10011001100110011001100
校验结果为0.5999999643,接近0.6但不完全相等。
4. 误差处理方法
为了避免浮点数运算的误差,可以采用以下方法:
- 将浮点数转换为整数:通过放大或缩小小数点进行运算,这样可以避免直接操作浮点数。
- 使用高精度库或大整数运算:例如,使用JavaScript的BigInt类型来处理大数,确保精度。
5. 结论
浮点数运算中的精度丢失问题是由于其二进制表示和运算机制的特性所决定的。理解这些原理有助于开发者在编写代码时更好地处理浮点数运算,避免因为精度问题导致的错误。通过采取适当的方法,如将浮点数转换为整数运算,可以有效减少误差,提高计算的准确性。
发表评论
最新留言
哈哈,博客排版真的漂亮呢~
[***.90.31.176]2025年04月06日 12时23分13秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
LeetCode Top-100 T22-括号生成
2019-03-11
svg基础+微信公众号交互(二)
2019-03-11
vscode设置eslint保存文件时自动修复eslint错误
2019-03-11
deepin 安装过程记录
2019-03-11
JAVA 多线程
2019-03-11
Java的 arraylist类【具体案例】
2019-03-11
删除DOM节点
2019-03-11
牛客-链表中环的入口节点(Java)
2019-03-11
【ARM自学笔记】ARM Cortex -A中断系统(程序篇)
2019-03-11
解决微信小程序中 calc 失效问题
2019-03-11
JS数组去重的方法
2019-03-11
堆的应用_topK算法和堆排序
2019-03-11
并查集(求连通块数量)
2019-03-11
最大半连通子图
2019-03-11
Remove Extra one 维护前缀最大最小值
2019-03-11
跳台阶
2019-03-11
另类加法,走方格的方案数,最近公共祖先
2019-03-11
线程学习5
2019-03-11
[Java Path Finder][JPF学习笔记][7]JPF输出详细程度设置
2019-03-11
GitHub完整记录数据库GHTorrent的下载和安装经验
2019-03-11