4

C# で System.Int64 に基づくQ31.32 固定小数点数値型を実装しています。現在、モジュロ演算を正しく取得しようとしています (%)。

私が見た固定小数点演算の実装はすべて、Qm.n モジュロを単純に整数モジュロで定義しています。つまり、2 つの Qm.n 数値のモジュロは、それらの基礎となる整数表現のモジュロです。これは一般的なケースでは機能しますが、次の 2 つの特定のケースでは失敗します。

  • x % yOverflowExceptionifx == Int64.MinValueと をスローしy == -1ます。これは if ステートメントで簡単に処理でき、この場合は 0 を返しますが、これは奇妙な動作です (そして、uncheckedここでは役に立ちません)。

  • x % yxとの一部の小さな値に対して誤って 0 を返しますy。たとえば、 と の整数表現がx( y10 進数: ~-0.000000096159 および ~0,000000013737) の場合、モジュロは-413( 10 進数: 0) であり、10 進数値のモジュロは (System.Decimal によると) ~-0.000000013737 です。 . このエラーは、型の最大精度 (2^-32) の約 60 倍であるため、丸めエラーとは見なされません。590

この最後のエラーの原因は何ですか?また、精度を上げるためにできることはありますか?

4

1 に答える 1

3

私は問題を発見しました。

-413 % 59 = 0 が正解!!!

-7 * 59 = -413 なので

想定される正しい結果は、-413 の 2 の補数から取得される可能性が高く、混乱につながります。

[編集1]

Asik の提案で、私は電卓を使用します。彼の質問に対する私の最後のコメントは正しかったです。問題は彼の印刷精度にあり、2 の補数またはモジュロを超えるものではありません。これを参照してください。

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 に答える