Nejlepší odpověď
Za prvé, gripe: C a C ++ jsou dva různé jazyky. Níže uvedená odpověď platí pro oba, ale někdy se odpověď v různých jazycích liší. A v obou jazycích má výraz c/c++
nedefinované chování.
Toto je praštěný způsob, jak získat typovou propagaci. Příklad v detailech je formulován jasněji:
int a, b;
long long l = a * 1ll * b;
Jak OP uvádí, 1ll
deklaruje celočíselný literál long long
.
Jeho přítomnost zde v kódu podporuje celé násobení na long long
prostřednictvím obvyklých aritmetických převodů, zejména celočíselné propagace.
Výraz se analyzuje jako ((a * 1ll) * b)
. První násobení pouze vrátí hodnotu a
jako long long
. Druhá multiplikace se poté upgraduje také na long long
.
Stejného efektu jste mohli dosáhnout s explicitním obsazením:
int a, b;
long long l = (long long)a * b;
Je to trochu více psaní, ale jen mírně. Druhá formulace je určitě jasnější, alespoň pro mě.
Můžete také udělat něco jako:
long long l = a;
l *= b;
Ale to už zase začíná být hloupé.
Pokud jde o to, proč musíte propagovat? Pokud máte dostatečně velké hodnoty, mohlo by dojít k přetečení násobení. Propagací na long long
zaručujete, že ne.
Předpokládejme 32bitové int
a 64- bit long long
a reprezentace doplňku 2. Největší produkt, který můžete získat, je -2 ^ {31} \ krát -2 ^ {31} = 2 ^ {62}. To je pod největší kladnou hodnotou, kterou můžete představovat, 2 ^ {63} – 1, takže máte zaručeno, že nepřeteknete.
Odpověď
a a b jsou int int * int -> int (vše v rozsahu 32 bitů int tj. -2147483648 int 2147483647) . „. 2147483647 * 2 = -2 a ne 4294967294 operátor přiřazení má asociativitu zprava doleva tj. Ve výrazu: long long l = a * b; a * b se vypočítá nejprve int * int-> int, pokud a = 2147483647 a b = 2 a * b -> – 2 a ne 4294967294 nyní l = -2-2 se převede na long long a uloží se do l