ステートメントlonglong l =(int)a * 1ll *(int)b;での1llの使用とはC / C ++の場合?


ベストアンサー

まず、不満:CとC ++は2つの異なる言語です。以下の答えはたまたま両方に当てはまりますが、言語によって答えが異なる場合があります。また、どちらの言語でも、式c/c++の動作は未定義です。

これはタイププロモーションを取得するための間抜けな方法。詳細の例は、より明確に定式化されていることに注意してください。

int a, b;

long long l = a * 1ll * b;

OPが注記しているように、1lllong long整数リテラルを宣言します。

そのここにコードが存在すると、通常の算術変換、特にiv id =を介して、乗算全体がlong longに昇格します。 “2e35d4f43c”>

整数プロモーション。

式は((a * 1ll) * b)として解析されます。最初の乗算では、aの値がlong longとして返されます。次に、2番目の乗算もlong longにアップグレードされます。

明示的なキャストで同じ効果を得ることができます:

int a, b;

long long l = (long long)a * b;

少し入力が多いですが、ほんの少しです。 2番目の定式化は、少なくとも私にとっては確かに明確です。

次のようなこともできます:

long long l = a;

l *= b;

しかし、それは再び愚かになり始めています。

なぜ宣伝する必要があるのですか?十分な大きさの値がある場合、乗算がオーバーフローする可能性があります。 long longに昇格することで、昇格しないことが保証されます。

32ビットのintと64ビットを想定しましょう。ビットlong long、および2の補数表現。取得できる最大の積は-2 ^ {31} \ times -2 ^ {31} = 2 ^ {62}です。これは、表現できる最大の正の値2 ^ {63} -1を下回っているため、オーバーフローしないことが保証されます。

回答

aとbはint int * int-> int(すべて32ビットintの範囲内 ie -2147483648 int 2147483647)。 “。2147483647 * 2 = -2であり、4294967294ではありません割り当て演算子には、右から左への関連付けがあります。 a * b; a * bは、a = 2147483647およびb = 2 a * b->-2であり、4294967294ではない場合に最初にint * int-> intとして計算され、l = -2-2はlonglongに変換され、lに格納されます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です