ベストアンサー
まず、不満:CとC ++は2つの異なる言語です。以下の答えはたまたま両方に当てはまりますが、言語によって答えが異なる場合があります。また、どちらの言語でも、式c/c++
の動作は未定義です。
これはタイププロモーションを取得するための間抜けな方法。詳細の例は、より明確に定式化されていることに注意してください。
int a, b;
long long l = a * 1ll * b;
OPが注記しているように、1ll
はlong 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に格納されます。