Bedste svar
For det første er et greb: C og C ++ er to forskellige sprog. Svaret nedenfor gælder tilfældigvis for begge, men nogle gange er svaret forskelligt mellem sprogene. Og på begge sprog har udtrykket c/c++
udefineret adfærd.
Dette er en tåbelig måde at få en type forfremmelse på. Bemærk, at eksemplet i detaljerne er formuleret mere tydeligt:
int a, b;
long long l = a * 1ll * b;
Som OP bemærker, erklærer 1ll
et long long
bogstaveligt heltal.
Dens tilstedeværelse her i koden fremmer hele multiplikationen til long long
gennem sædvanlige aritmetiske konverteringer, især heltalskampagner.
Udtrykket tolkes som ((a * 1ll) * b)
. Den første multiplikation returnerer bare værdien af a
som en long long
. Den anden multiplikation opgraderes derefter til long long
.
Du kunne have fået den samme effekt med en eksplicit rollebesætning:
int a, b;
long long l = (long long)a * b;
Det skriver lidt mere, men kun lidt. Den anden formulering er bestemt klarere, i det mindste for mig.
Du kan også gøre noget som:
long long l = a;
l *= b;
Men det begynder at blive fjollet igen.
Hvad angår hvorfor skal du promovere? Hvis du har store nok værdier, kan multiplikationen løbe over. Ved at promovere til long long
garanterer du, at du ikke vil.
Lad os antage, at 32-bit int
og 64- bit long long
, og 2er supplerer repræsentation. Det største produkt, du kan få, er -2 ^ {31} \ times -2 ^ {31} = 2 ^ {62}. Det er under den største positive værdi, du kan repræsentere, 2 ^ {63} – 1, så du er garanteret, at du ikke løber over.
Svar
a og b er int int * int -> int (alt inden for rækkevidde af 32 bit int ie -2147483648 int 2147483647) . “. 2147483647 * 2 = -2 og ikke 4294967294 tildelingsoperatør har tilknytning fra højre til venstre dvs. i udtrykket: lang lang l = a * b; a * b beregnes første int * int-> int hvis a = 2147483647 og b = 2 a * b -> – 2 og ikke 4294967294 nu konverteres l = -2-2 til lang lang og gemmes i l