Care este utilizarea lui 1ll în declarația long long l = (int) a * 1ll * (int) b; în C / C ++?


Cel mai bun răspuns

În primul rând, o problemă: C și C ++ sunt două limbi diferite. Răspunsul de mai jos se aplică ambelor, dar uneori răspunsul diferă între limbi. Și, în ambele limbi, expresia c/c++ are comportament nedefinit.

Acesta este un mod prost pentru a obține o promoție de tip. Rețineți că exemplul din detalii este formulat mai clar:

int a, b;

long long l = a * 1ll * b;

După cum notează OP, 1ll declară un literal long long întreg.

prezența aici în cod promovează întreaga multiplicare la long long prin conversii aritmetice obișnuite, în special promoții întregi.

Expresia se analizează ca ((a * 1ll) * b). Prima multiplicare returnează doar valoarea a ca long long. Cea de-a doua multiplicare se actualizează apoi la long long.

Ați fi putut obține același efect cu o distribuție explicită:

int a, b;

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

Este puțin mai tare, dar doar puțin. A doua formulare este cu siguranță mai clară, cel puțin pentru mine.

Ați putea face și ceva de genul:

long long l = a;

l *= b;

Dar asta începe să devină din nou prostesc.

În ceea ce privește motivul pentru care trebuie să promovați? Dacă aveți valori suficient de mari, multiplicarea s-ar putea revărsa. Prin promovarea la long long, vă asigurați că nu o veți face.

Să presupunem că pe 32 de biți int și 64- bit long long și reprezentarea complementului 2. Cel mai mare produs pe care îl puteți obține este -2 ^ {31} \ times -2 ^ {31} = 2 ^ {62}. Aceasta este sub cea mai mare valoare pozitivă pe care o puteți reprezenta, 2 ^ {63} – 1, astfel încât să vă asigurați că nu veți revărsa.

Răspuns

a și b sunt int int * int -> int (toate în intervalul de 32 biți int ie -2147483648 int 2147483647) . „. 2147483647 * 2 = -2 și nu 4294967294 operatorul de atribuire are asociativitate de la dreapta la stânga adică în expresia: lung lung l = a * b; a * b se calculează mai întâi int * int-> int dacă a = 2147483647 și b = 2 a * b -> – 2 și nu 4294967294 acum l = -2 -2 este convertit în lung lung și stocat în l

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *