1

1)これはオーバーフローできませんか?

long long v1, v2, result;
[..]
result = ((long double) v1 / v2) * 1000000LL;

1.a)定数のLLを省略できますか?なぜ。

2)あるいは、フロートなしのこのバリエーションは大丈夫ですか?

long long l1, l2, result;
[..]
result = (1000000 * (v1 / v2) + v1 % v2);

2.a)オーバーヘッドが多いのはどれですか?最初の例またはこの例?

3)フロートがオーバーフローすることはありますか、それとも「正常な」値にラップするだけですか?

4

2 に答える 2

2

はい、例(1)の結果は、たとえばv1=1000000000000000およびv2=1の場合、簡単にオーバーフローする可能性があります。この定数のLLは、int(ほとんどの実装では、場合)。

(2)v1とv2が私が与えたとおりである場合、例1と同様にオーバーフローする可能性があります。

最初の例は、浮動小数点演算が整数演算よりも高価であるため、より高価です。

(3)フロートは確かにオーバーフローする可能性があり、その結果は実装に依存します。

Arjitが指摘しているように、計算を実行する前にv1の値をチェックすることで、オーバーフローを防ぐことができます。v1がネガティブである可能性がある場合は、ネガティブバージョンも確認する必要があり、おそらく次の方が良いかもしれません...

if ((LONG_LONG_MAX / 1000000) > V1)
{
...
}

本当に限界に達している場合は、変数を。と宣言することで、もう少し余裕を持たせることができますunsigned

後で-Arjitが指摘した間違いを修正するために編集します。

于 2010-08-09T09:06:29.107 に答える
1

まず、

  1. INTまたはLong計算を行う場合は、floatを使用しないでください。最初の部分の結果には、ほぼ等しい多くの異なる値が含まれるためです。

(float)v1 / v2=ab.cdefだからです。//cdefは変化する可能性があります。

v1 = 2^15およびv2=1の場合、2番目の実装でもオーバーフローが発生する可能性があります

したがって、オーバーフローとセキュリティを探している場合は、常にチェックする必要があります

2 ^ 18 / Constantのように、この場合は1000000です

それで

if(2^18/Constant > v1)

    result = (1000000 * (v1 / v2) + v1 % v2);

これはハッキングの証拠になります。

お役に立てれば

于 2010-08-09T08:55:27.827 に答える