Was ist die Verwendung von 1ll in der Anweisung long long l = (int) a * 1ll * (int) b; in C / C ++?


Beste Antwort

Zunächst ein Kritikpunkt: C und C ++ sind zwei verschiedene Sprachen. Die folgende Antwort gilt für beide, aber manchmal unterscheidet sich die Antwort zwischen den Sprachen. In beiden Sprachen hat der Ausdruck c/c++ undefiniertes Verhalten.

Dies ist ein doof Weg, um eine Typ Promotion zu bekommen. Beachten Sie, dass das Beispiel im Detail klarer formuliert ist:

int a, b;

long long l = a * 1ll * b;

Wie das OP feststellt, deklariert die 1ll ein long long ganzzahliges Literal.

Its Das Vorhandensein hier im Code fördert die gesamte Multiplikation zu long long durch die üblichen arithmetischen Konvertierungen , insbesondere die Ganzzahl-Promotions.

Der Ausdruck wird als ((a * 1ll) * b) analysiert. Die erste Multiplikation gibt nur den Wert von a als long long zurück. Die zweite Multiplikation wird dann ebenfalls auf long long aktualisiert.

Sie hätten den gleichen Effekt mit einer expliziten Besetzung erzielen können:

int a, b;

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

Es wird etwas mehr getippt, aber nur geringfügig. Die zweite Formulierung ist zumindest für mich sicherlich klarer.

Sie können auch Folgendes tun:

long long l = a;

l *= b;

Aber das wird wieder albern.

Warum müssen Sie Werbung machen? Wenn Sie ausreichend große Werte haben, kann die Multiplikation überlaufen. Wenn Sie auf long long hochstufen, garantieren Sie dies nicht.

Nehmen wir an, dass 32-Bit int und 64- Bit long long und 2s Komplementdarstellung. Das größte Produkt, das Sie erhalten können, ist -2 ^ {31} \ times -2 ^ {31} = 2 ^ {62}. Dies liegt unter dem größten positiven Wert, den Sie darstellen können, 2 ^ {63} – 1, sodass Sie garantiert nicht überlaufen.

Antwort

a und b sind int int * int -> int (alle im Bereich von 32 Bit int dh -2147483648 int 2147483647) . „. 2147483647 * 2 = -2 und nicht 4294967294 Zuweisungsoperator hat Assoziativität von rechts nach links dh im Ausdruck: long long l = a * b; a * b wird zuerst berechnet int * int-> int wenn a = 2147483647 und b = 2 a * b -> – 2 und nicht 4294967294 jetzt l = -2 -2 wird in long long konvertiert und in l gespeichert

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.