Wat is het gebruik van 1ll in statement long long l = (int) a * 1ll * (int) b; in C / C ++?


Beste antwoord

Ten eerste een klacht: C en C ++ zijn twee verschillende talen. Het onderstaande antwoord is toevallig op beide van toepassing, maar soms verschilt het antwoord tussen de talen. En in beide talen heeft de uitdrukking c/c++ ongedefinieerd gedrag.

Dit is een gekke manier om een ​​typepromotie te krijgen. Merk op dat het voorbeeld in de details duidelijker is geformuleerd:

int a, b;

long long l = a * 1ll * b;

Zoals het OP opmerkt, declareert de 1ll een long long letterlijk geheel getal.

aanwezigheid hier in de code bevordert de volledige vermenigvuldiging naar long long via de gebruikelijke rekenkundige conversies , met name de promoties met gehele getallen.

De uitdrukking wordt geparseerd als ((a * 1ll) * b). De eerste vermenigvuldiging retourneert alleen de waarde van a als een long long. De tweede vermenigvuldiging wordt vervolgens geüpgraded naar long long.

Je had hetzelfde effect kunnen krijgen met een expliciete cast:

int a, b;

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

Het is iets meer typen, maar slechts een klein beetje. De tweede formulering is zeker duidelijker, althans voor mij.

Je zou ook zoiets kunnen doen als:

long long l = a;

l *= b;

Maar dat begint weer gek te worden.

Waarom moet je promoten? Als je waarden hebt die groot genoeg zijn, kan de vermenigvuldiging overlopen. Door te promoveren naar long long, garandeer je dat je dat niet zult doen.

Laten we aannemen dat 32-bits int en 64- bit long long, en 2s complement representatie. Het grootste product dat u kunt krijgen is -2 ^ {31} \ maal -2 ^ {31} = 2 ^ {62}. Dat is onder de grootste positieve waarde die u kunt vertegenwoordigen, 2 ^ {63} – 1, dus u bent er zeker van dat u niet overloopt.

Antwoord

a en b zijn int int * int -> int (allemaal binnen het bereik van 32 bit int ie -2147483648 int 2147483647) . “. 2147483647 * 2 = -2 en niet 4294967294 toewijzingsoperator heeft associativiteit van rechts naar links dwz in de uitdrukking: long long l = a * b; a * b wordt als eerste berekend int * int-> int als a = 2147483647 en b = 2 a * b -> – 2 en niet 4294967294 nu wordt l = -2-2 omgezet in long long en opgeslagen in l

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *