floating-point - 二进制浮点加法算法
问题描述
我试图在二进制级别上理解 IEEE 754 浮点加法。我遵循了一些我在网上找到的示例算法,并且大量的测试用例与经过验证的软件实现相匹配。我的算法目前只处理正数。但是,我没有与此测试用例匹配:
00001000111100110110010010011100 (1.46487e-33)
00000000000011000111111010000100 (1.14741e-39)
我把它分成符号位、指数、尾数。我将隐含的 1 添加回尾数
0 00010001 1.11100110110010010011100
0 00000000 1.00011000111111010000100
我从较小的指数中减去较大的指数以确定重新对齐移位量:
00010001 (17)
-00000000 (0)
=============
17
我在尾数上添加了 Guard bit、Round Bit 和 Sticky Bit:
1.11100110110010010011100 000
1.00011000111111010000100 000
我将较小值的尾数向右移动 17 次,一旦接收到 1,LSb 就会“粘住”:
0.00000000000000001000110 001
我将较大的尾数添加到移位的较小尾数中:
1.11100110110010010011100 000 +
0.00000000000000001000110 001
================================
1.11100110110010011100010 001
由于没有溢出,并且保护位为 0,我可以直接使用 summation-mantissa 和更大的指数(重新删除隐含的 '1'):
0 00010001 11100110110010011100010
给出最终值:
00001000111100110110010011100010 (1.46487e-33)
但根据我的验证实现,我应该得到:
00001000111100110110010010101000 (1.46487e-33)
非常接近但不准确。我的算法有错误吗?
解决方案
计算中似乎存在两个问题,都与将次正规数视为正常数有关:
- 班次计算不正确。指数是-126,而不是-127。
- 在二进制点之前错误地插入一位。
这是修改后的计算:
0 00010001 1.11100110110010010011100
0 00000000 0.00011000111111010000100
在尾数上添加 Guard bit、Round Bit 和 Sticky Bit:
1.11100110110010010011100 000
0.00011000111111010000100 000
较小数字的 16 位右移。
0.00000000000000000001100 001
将大尾数添加到移位的小尾数:
1.11100110110010010011100 000 +
0.00000000000000000001100 001
================================
1.11100110110010010101000 001
推荐阅读
- html - 使用媒体查询,如何使其工作?
- javascript - 如何读取动态字符串作为对象引用
- firebase-dynamic-links - 对 Firebase 动态链接和 Wix 网站使用相同的域名
- python - python:如何计算结构张量的特征值和特征向量?
- python - 将 FFMPEG 添加到 macOS 路径以在 Python 中将 mp3 转换为 WAV 的问题
- json - Javascript - 从对象中获取返回 json
- javascript - 如何解决 slick.js 的“未捕获的类型错误:无法读取未定义的属性”
- java - Gson @AutoValue 和 Optional<> 不能一起工作,有解决方法吗?
- java - 如何在处理 DataIntegrityViolationException 时获取密钥的名称?
- laravel - 如何初始化一个组件