警告
この方法は部分的にしか機能しません。解決できない場合があります。
あなたのテキストから取られた:
タイプab-cdの違いを解決するアルゴリズムを探しています。ここで、a、b、c、およびdは、タイプ容量の端にある整数です。
(a * b) - (c * d)
私が理解しているように、あなたは数値オーバーフローを避けて計算したいと思っています。そして、あなたはこれをアルゴリズムで解決したいと思っています。
最初に認識する必要があるのは、の結果が(a * b) - (c * d)
データ型に適合しない可能性があるということです。私はそれらのケースを解決しようとはしません。
そこで、「ab-cd」を計算するさまざまな方法を探します。私が見つけたのはこれです:
(a * b) - (c * d) = ((a - c) * b) - (c * (d - b))
変数を並べ替えてさまざまな製品を取得できるため、恐ろしい数値オーバーフローなしで演算を計算できるケースを見つける可能性が高くなります。
((a - d) * b) - (d * (c - b))
((b - c) * a) - (c * (d - a))
((a - c) * b) - (c * (d - b))
((b - d) * c) - (b * (c - a))
((a - d) * c) - (a * (c - b))
((b - c) * d) - (b * (d - a))
((a - c) * d) - (a * (d - b))
また、これはまだ製品の違いであることに注意してください。つまり、機能する製品が見つかるまで、それらを再帰的に適用できます。例えば:
Starting with:
(a * b) - (c * d)
=>
Using the transformation:
((a - d) * b) - (d * (c - b))
=>
By substitution:
(e * b) - (d * f)
=>
Rinse an repeat:
((e - f) * b) - (f * (d - b))
もちろん、これを行うことで数値オーバーフローが発生しないようにする必要があります。ありがたいことに、次のアプローチを使用して、特定の製品が(実際に製品を実行せずに)数値オーバーフローを引き起こすかどうかをテストすることもできます。
var max = MaxValue;
var min = MinValue;
if (a == 0 || b == 0)
{
return false;
}
else
{
var lim = a < 0 != b < 0 ? min : max;
if ((a < 0 == b < 0) == a < 0)
{
return lim / a > b;
}
else
{
return lim / a < b;
}
}
また、次の方法で、特定の違いが(実際に違いを実行せずに)数値オーバーフローを引き起こすかどうかをテストすることもできます。
var max = MaxValue;
var min = MinValue;
if (a < 0 == b < 0)
{
return true;
}
else
{
if (a < 0)
{
if (b > 0)
{
return min + b < a;
}
else
{
return min - b < a;
}
}
else
{
if (b > 0)
{
return max - b > a;
}
else
{
return max + b > a;
}
}
}
これにより、数値オーバーフローなしで計算できる上記の8つの式から式を選択することができます。
しかし...時々それらのどれもうまくいきません。そして、それらの組み合わせでさえうまくいかない場合があるようです(つまり、すすぎと繰り返しがうまくいかない)*。たぶん、絵を完成させることができる他のアイデンティティがあります。
*:いくつかのヒューリスティックを使用して組み合わせを探索し、ランダムな探索も試みました。適切なヒューリスティックを選択しなかった可能性があり、ランダムで「運」がなかった可能性があります。だからはっきりとは言えません。
私はある程度の進歩を遂げたと思いたいです...しかし、元の問題に関しては、私は最終的に失敗しました。時間があればこの問題に戻るかもしれません...あるいはビデオゲームをプレイするだけかもしれません。