我正在C#中实现基于System.Int64的Q31.32 fixed-point numeric type。现在我正在尝试正确地进行模运算(%)。
我见过的定点运算的所有实现都只是用整数模来定义Qm.n模数,即两个Qm.n数的模数是它们的基础整数表示的模数。这适用于一般情况,但在两个特定情况下失败:
x % y
和OverflowException
,则 x == Int64.MinValue
会引发y == -1
。
我可以使用if语句轻松处理此问题并返回0 in
在这种情况下,虽然这是一种奇怪的行为(unchecked
在这里没有帮助。)
x % y
错误地为x
和y
的一些小值返回0。对于
例如,如果x
和y
的整数表示为-413
和59
(十进制:〜-0.000000096159和~0,000000013737),模数为0
(十进制:0),而其十进制值的模数为(根据System.Decimal)
〜-0.000000013737。这个错误大约是60倍
类型的最大精度(2 ^ -32),因此不能认为是
舍入错误。
这最后一次错误的原因是什么?我能做些什么来获得更好的准确度吗?
答案 0 :(得分:2)
我发现了问题。
-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
P.S。你是如何获得模数应该是〜-0.000000013737的结果?它可疑地等于-59>> 32 ...也许你的参考不能正确处理有符号数(-413)<(59)并且因为它(以避免除法)而将模数的结果简单地抛出59两个数字相结合。