数年前に興味深い理論上の問題に遭遇しました。私は解決策を見つけたことがなく、寝るときも悩み続けます。
xと呼ばれるintに数値を保持する(C#)アプリケーションがあるとします。(xの値は固定されていません)。プログラムが実行されると、xに33が掛けられ、ファイルに書き込まれます。
基本的なソースコードは次のようになります。
int x = getSomeInt();
x = x * 33;
file.WriteLine(x); // Writes x to the file in decimal format
数年後、Xの元の値が必要であることを発見します。一部の計算は簡単です。ファイル内の数値を33で除算するだけです。ただし、他の場合では、Xが十分に大きいため、乗算によって整数オーバーフローが発生します。ドキュメントによると、C#は数値が未満になるまで高位ビットを切り捨てint.MaxValue
ます。この場合、次のいずれかが可能ですか?
- X自体を回復するか
- Xの可能な値のリストを回復しますか?
単純な加算のケースが機能するため(基本的にXに10を加算してラップすると、10を減算してXで終了することができるので、一方または両方が可能になるはずです(私のロジックは確かに欠陥がある可能性があります) )そして、乗算は単純に繰り返される加算です。また、Xがすべての場合に同じ値-定数33で乗算されるという事実も役立ちます(私は信じています)。
これは何年も奇妙な瞬間に私の頭蓋骨の周りで踊っています。それは私に起こるでしょう、私はそれを熟考しようといくつかの時間を費やすでしょう、そして私はそれを数ヶ月間忘れます。この問題を追いかけるのはうんざりです!誰でも洞察を提供できますか?
(サイドノート:私は本当にこれにタグを付ける方法を知りません。提案を歓迎します。)
編集: Xの可能な値のリストを取得できる場合、元の値に絞り込むのに役立つ他のテストがあることを明確にしましょう。
m
2 ^ 32または2 ^ 64であり、a
モジュロのべき乗m
が単純である(オーバーフローを無視するだけ)
r*s^-1 mod m
あなたは両方を見つける必要があるr
とs
。ここで、私たちはr*s mod m
すべてを知っていr
ます。