作为一个学习项目,我正在使用c++在软件中实现浮点数操作(加、减、乘、除)。目标是更加熟悉浮点数行为的基本细节。
我尝试将处理器操作与精确的比特匹配,即IEEE 754标准。到目前为止,它运行得很好,加、减和乘法表现完美,我在大约1.1亿个随机操作中进行了测试,并得到了与处理器在硬件上执行的完全相同的结果。(虽然没有考虑边缘情况、溢出等)。
之后,我开始转向最后一个操作,即除法。它可以正常工作并达到预期结果,但是有时候我会发现最后一位尾数错误,未对其进行四舍五入。我有点难以理解为什么。
我主要参考的是John Farrier 的优秀演讲(时间戳显示如何进行四舍五入)。
我得到的最终结果是:
我的:0-01111111-01001111001000111100000
C++:0-01111111-01001111001000111100001
可以看到除了最后一位之外,其他都匹配。 我计算除法的方式基于这个视频: https://www.youtube.com/watch?v=fi8A4zz1d-s
根据John Farrier的视频,在100 grs位的情况下,如果尾数的最低有效位是1,我只会进行规格化。在我的情况下,它是0,这就是为什么我不会将结果四舍五入的原因。
我有点迷茫的原因是我确信我的算法正在计算正确的尾数,我已经用在线计算器仔细检查过了,舍入策略对于所有其他操作都有效。此外,以这种方式计算会触发规范化,最终得到正确的指数。
我错过了什么吗?哪里有小细节?
有一件事让我感到奇怪的是粘性位,在加法和乘法中,您会获得不同程度的移位,这导致更高的粘性位触发几率,在这种情况下,我最多只能移动一个位数,这使得粘性位不是真正的粘性。
我希望我提供足够的细节来理解我的问题。在此处,您可以在底部找到我的除法实现,其中填充了我用于调试的打印内容,但应该可以了解我正在做什么,代码从第374行开始:
我尝试将处理器操作与精确的比特匹配,即IEEE 754标准。到目前为止,它运行得很好,加、减和乘法表现完美,我在大约1.1亿个随机操作中进行了测试,并得到了与处理器在硬件上执行的完全相同的结果。(虽然没有考虑边缘情况、溢出等)。
之后,我开始转向最后一个操作,即除法。它可以正常工作并达到预期结果,但是有时候我会发现最后一位尾数错误,未对其进行四舍五入。我有点难以理解为什么。
我主要参考的是John Farrier 的优秀演讲(时间戳显示如何进行四舍五入)。
https://youtu.be/k12BJGSc2Nc?t=1153
那个四舍五入对于所有运算都很有效,但对于除法却给我带来了麻烦。 让我举个具体的例子。 我正试图将 645.68011474609375 除以 493.20962524414063。我得到的最终结果是:
我的:0-01111111-01001111001000111100000
C++:0-01111111-01001111001000111100001
可以看到除了最后一位之外,其他都匹配。 我计算除法的方式基于这个视频: https://www.youtube.com/watch?v=fi8A4zz1d-s
接下来,我计算了28位精度为24的尾数(隐含1 + 23个尾数)和3位保护位、四舍五入位再加上一个可能的移位的额外位。 使用视频中的算法,我最多可以获得1个归一化移位,这就是为什么我在结尾处有一个额外的位,以防它在归一化中被移动,因此在舍入中可用。现在,以下是我从除法算法中得到的结果:
010100111100100011110000 0100
------------------------ ----
^ grs^
|__ to be normalized |____ extra bit
正如您所看到的,我在第24个位置得到了0,因此我需要向左移动一个位置以获得正确的归一化。这意味着我将得到:
10100111100100011110000 100
根据John Farrier的视频,在100 grs位的情况下,如果尾数的最低有效位是1,我只会进行规格化。在我的情况下,它是0,这就是为什么我不会将结果四舍五入的原因。
我有点迷茫的原因是我确信我的算法正在计算正确的尾数,我已经用在线计算器仔细检查过了,舍入策略对于所有其他操作都有效。此外,以这种方式计算会触发规范化,最终得到正确的指数。
我错过了什么吗?哪里有小细节?
有一件事让我感到奇怪的是粘性位,在加法和乘法中,您会获得不同程度的移位,这导致更高的粘性位触发几率,在这种情况下,我最多只能移动一个位数,这使得粘性位不是真正的粘性。
我希望我提供足够的细节来理解我的问题。在此处,您可以在底部找到我的除法实现,其中填充了我用于调试的打印内容,但应该可以了解我正在做什么,代码从第374行开始:
https://gist.github.com/giordi91/1388504fadcf94b3f6f42103dfd1f938
PS:同时,我正在学习“科学家应该了解的浮点数知识”,以便查看是否有遗漏的内容。