4

我正在C# 中实现基于 System.Int64的Q31.32 定点数值类型。现在我正在尝试正确地进行模运算(%)。

我见过的所有定点算术的实现都简单地根据整数模来定义 Qm.n 模,即两个 Qm.n 数的模是它们底层整数表示的模。这在一般情况下有效,但在两种特定情况下失败:

  • x % y抛出一个OverflowExceptionifx == Int64.MinValuey == -1. 在这种情况下,我可以使用 if 语句轻松处理此问题并返回 0,尽管这是一种奇怪的行为(unchecked在这里没有帮助)。

  • x % y对于 和的一些小值,错误地返回x0 y。例如,如果和的整数表示是和(x十进制 :~-0.000000096159 和~0,000000013737),则模为 (十进制:0),而其十进制值的模为(根据 System.Decimal)~-0.000000013737 . 这个误差比类型的最大精度 (2^-32) 大约大 60 倍,因此不能认为是舍入误差。y-413590

最后一个错误的原因是什么,我可以做些什么来获得更好的准确性?

4

1 回答 1

3

我发现了问题。

-413 % 59 = 0 是正确的!!!

因为 -7 * 59 = -413

您假设的正确结果很可能取自-413 的2s 补码,这会导致混淆。

[编辑 1]

在 Asik 的建议下,我使用计算器,我对他的问题的最后评论是正确的。问题在于他的打印精度,而不是高于 2s 补码或模数,请参见:

413 >> 32 = 0.00000009615905582904815673828125  
 59 >> 32 = 0.00000001373700797557830810546875

0.00000009615905582904815673828125 / 0.00000001373700797557830810546875 = 7
0.00000009615905582904815673828125 % 0.00000001373700797557830810546875 = 0

有关打印数字的更多信息,请参见:https ://stackoverflow.com/a/18401040/2521214

PS您究竟是如何获得模数应该为 ~-0.000000013737 的结果?它可疑地等于 -59>>32 ...也许您的参考无法正确处理带符号的数字 (-413)<(59) 并仅抛出模 59 的结果,因为它(以避免除法)与符号组合两个数字。

于 2013-10-14T18:37:32.020 回答