1

これに対する解決策は実際には必要ありません。理由を知りたいだけです。2 つの数値を考えてみましょう。

#include <iostream>
using namespace std;

int main()
{
    unsigned long long int a = 17446744073709551615;
    signed long long int b = -30000000003;
    signed int c;
    c = a/b;
    cout << "\n\n\n" << c << endl;
}

さて、最近私が得ている答えはゼロです。私の long long のサイズは 8 バイトなので、unsigned ラベルを付けるには十分すぎるサイズです。C 変数も、答えを処理するのに十分な大きさである必要があります。(Google によると、-581 558 136 のはずです)。そう...

編集私は自分のマシンでそれを指摘したいと思います...

numeric_limits を使用すると、a は 18446744073709551615 の最大値内に収まり、b は -9223372036854775808 の最小値内に収まります。

4

2 に答える 2

7

多くの暗黙的な変換が発生していますが、そのほとんどは不要です。

unsigned long long int a = 17446744073709551615;

接尾辞なしの 10 進整数リテラルの型intは 、long int、またはlong long intです。署名されていないタイプではありません。その特定の値は、ほぼ確実に a long long int(2 63 -1) の最大値を超えています。コンパイラが 64 ビットを超える符号付き整数型を持っていない限り、プログラムの形式が正しくありません。

ULLリテラルが正しい型であることを確認するためにサフィックスを追加します。

unsigned long long int a = 17446744073709551615ULL;

値はたまたま 2 63 -1 から 2 64 -1 の間であるため、64 ビット符号なし型には適合しますが、64 ビット符号付き型には適合しません。

(実際には だけでU十分ですが、明示的にしても害はありません。)

signed long long int b = -30000000003;

これは問題にはなりません。30000000003符号付き整数型です。コンパイラlong longが少なくとも 64 ビット幅の をサポートしている場合、オーバーフローはありません。それでも、 の値に接尾辞が必要な限り、a明示的に指定しても問題ありません。

signed long long int b = -30000000003LL;

これで、次のようになりました。

signed int c;
c = a/b;

unsigned long longを a で割るsigned long longと、符号付きオペランドが に変換されunsigned long longます。この場合、変換される値は負であるため、大きな正の値に変換されます。利回りに変換-30000000003します。で割るとゼロになります。unsigned long long184467440437095516131744674407370955161518446744043709551613

コンパイラが 64 ビットを超える整数をサポートしていない限り (ほとんどの場合サポートしていません)、直接除算17446744073709551615-30000000003て数学的に正しい答えを得ることができません。これは、両方の値を表すことができる整数型がないためです。すべての算術演算子 (シフト演算子を除く) には、同じ型のオペランドが必要であり、必要に応じて暗黙的な変換が適用されます。

この特定のケースでは、除算17446744073709551615ULL30000000003ULLて符号を考慮することができます。(負の整数の除算については、言語規則を確認してください。)

一般的にこれを本当に行う必要がある場合は、浮動小数点に頼ることができます (つまり、精度がいくらか失われる可能性があります) か、GMPのような任意幅の整数演算パッケージを使用できます。

于 2014-02-16T04:53:26.563 に答える
0

b は、a より大きい符号なしの数値として扱われています。したがって、答えは 0 になります。

として使ってみてください

c = abs(a) / abs (b)
if ((a < 0 && b > 0 ) || (a> 0 && b < 0))
   return -c;
return c;
于 2014-02-16T04:40:53.440 に答える