In von Apple erstelltem Code gibt es folgende Zeile:
CMTimeMakeWithSeconds( newDurationSeconds, 1000*1000*1000 )
Gibt es einen Grund, sich auszudrücken 1,000,000,000
als 1000*1000*1000
?
Warum nicht 1000^3
?
quelle
In von Apple erstelltem Code gibt es folgende Zeile:
CMTimeMakeWithSeconds( newDurationSeconds, 1000*1000*1000 )
Gibt es einen Grund, sich auszudrücken 1,000,000,000
als 1000*1000*1000
?
Warum nicht 1000^3
?
Ein Grund, Konstanten multiplikativ zu deklarieren, besteht darin, die Lesbarkeit zu verbessern, während die Laufzeitleistung nicht beeinträchtigt wird. Auch um anzuzeigen, dass der Autor multiplikativ über die Zahl nachdachte.
Bedenken Sie:
double memoryBytes = 1024 * 1024 * 1024;
Es ist eindeutig besser als:
double memoryBytes = 1073741824;
da letzterer auf den ersten Blick nicht die dritte Potenz von 1024 sieht.
Wie Amin Negm-Awad erwähnte, ist der ^
Operator die Binärdatei XOR
. In vielen Sprachen fehlt der integrierte Exponentiationsoperator zur Kompilierungszeit, daher die Multiplikation.
x
, um die Größe des Unterbereichs zu erhalten ... und plötzlich haben Sie einen Bruchteil Byte, für dessen Kompensation möglicherweise zusätzliche Logik erforderlich ist.
Warum nicht
1000^3
?
Das Ergebnis von 1000^3
ist 1003. ^
ist der Bit-XOR-Operator.
Auch wenn es nicht um das Q selbst geht, füge ich eine Klarstellung hinzu. x^y
ist nicht bewerten immer x+y
wie es funktioniert in dem Beispiel des Fragestellers . Sie müssen jedes Bit xor. Im Fall des Beispiels:
1111101000₂ (1000₁₀)
0000000011₂ (3₁₀)
1111101011₂ (1003₁₀)
Aber
1111101001₂ (1001₁₀)
0000000011₂ (3₁₀)
1111101010₂ (1002₁₀)
^
Operator bedeutet XOR in C / C ++ / Objective-C usw. In Taschenrechnern bedeutet dies normalerweise x-zu-y-Potenz.
Es gibt Gründe, nicht zu verwenden1000 * 1000 * 1000
.
Mit 16-Bit int
, 1000 * 1000
überläuft. Also mit1000 * 1000 * 1000
verringert also die Portabilität.
Bei 32-Bit läuft int
die folgende erste Codezeile über.
long long Duration = 1000 * 1000 * 1000 * 1000; // overflow
long long Duration = 1000000000000; // no overflow, hard to read
Schlagen Sie vor, dass der Lead-Wert hinsichtlich Lesbarkeit, Portabilität und Korrektheit mit dem Typ des Ziels übereinstimmt .
double Duration = 1000.0 * 1000 * 1000;
long long Duration = 1000LL * 1000 * 1000 * 1000;
Könnte auch einfach e
Notation für Werte verwenden, die genau als dargestellt werden können double
. Dies führt natürlich zu der Erkenntnis, ob double
der gesamte Zahlenwert genau dargestellt werden kann - was bei Werten größer als 1e9 von Belang ist. (Siehe DBL_EPSILON
und DBL_DIG
).
long Duration = 1000000000;
// vs.
long Duration = 1e9;
double
kann genau alle ganzen Zahlen bis zu 2 ^ 53 ≈ 9e15 darstellen.
double
Verwendung von binary64 an, obwohl es sehr häufig verwendet wird. Gemäß der C-Spezifikation sind Werte bis etwa 1e9 genau darstellbar. Es hängt davon ab, ob Sie nach Spezifikation codieren oder sich auf gängige Praktiken verlassen möchten.
1000
und 1000000000000
sind ganzzahlige Konstanten . Jeder unabhängig mit hat den Typ ausgewählt aus int
, long
oder long long
. Der Compiler verwendet den ersten Typ der 3, in den die Ganzzahlkonstante passt. 1000 * 1000 * 1000 * 1000
wird mit int
Mathe wie jeder 1000
in einem gemacht int
. Das Produkt läuft mit 32-Bit über int
. 1000000000000
ist sicherlich als long long
(oder möglicherweise enger) darstellbar - kein Überlauf. Der Typ des Ziels long long Duration
hat keinen Einfluss auf diese "rechte Seite der =" Detemrination.
int
, long x = 1000 * 1000 * 1000L;
würde überlaufen, während long x = 1000L * 1000 * 1000;
würde nicht.
Zur besseren Lesbarkeit.
Das Platzieren von Kommas und Leerzeichen zwischen den Nullen ( 1 000 000 000
oder 1,000,000,000
) würde einen Syntaxfehler erzeugen, und wenn 1000000000
der Code vorhanden ist, ist es schwierig, genau zu erkennen, wie viele Nullen vorhanden sind.
1000*1000*1000
macht deutlich, dass es 10 ^ 9 ist, weil unsere Augen die Brocken leichter verarbeiten können. Außerdem fallen keine Laufzeitkosten an, da der Compiler diese durch die Konstante ersetzt 1000000000
.
1,000,000,000
würde kein Syntaxfehler auftreten, sondern nur etwas anderes. Zum BeispielCMTimeMakeWithSeconds( newDurationSeconds, 1,000,000,000 )
1_000_000_000
_
als Trennzeichen :)
'
Trennzeichen in C ++ 14 erhalten, damit Sie es verwenden können 1'000'000'000
. (Es wurde ausgewählt, weil 1,000,000,000
es als Kommaoperator oder 4 verschiedene Parameter falsch interpretiert werden kann und _1_000_000_000
ein gültiger (aber wahrscheinlich schlechter) Variablenname ist.)
Zur besseren Lesbarkeit. Zum Vergleich unterstützt Java _
in Zahlen, um die Lesbarkeit zu verbessern (zuerst vorgeschlagen von Stephen Colebourne als Antwort auf Derek Fosters VORSCHLAG: Binäre Literale für Project Coin / JSR 334). Man würde 1_000_000_000
hier schreiben .
In ungefähr chronologischer Reihenfolge, vom ältesten bis zum neuesten Support:
"(1)1111 1111"
( anscheinend nicht für Dezimalwerte, sondern nur für Bitstrings, die Binär-, Quartal-, Oktal- oder Hexadezimalwerte darstellen )1$000$000
1_000_000_000
1'000'000'000
Es ist eine relativ neue Funktion für Sprachen, um zu erkennen, dass sie unterstützt werden sollten (und dann gibt es Perl). Wie in der ausgezeichneten Antwort von chux @ 1000*1000...
ist dies eine Teillösung, öffnet den Programmierer jedoch für Fehler, die durch Überlaufen der Multiplikation entstehen, selbst wenn das Endergebnis ein großer Typ ist.
Könnte einfacher zu lesen sein und einige Assoziationen mit dem 1,000,000,000
Formular erhalten.
Aus technischer Sicht gibt es wohl keinen Unterschied zwischen der direkten Zahl oder der Multiplikation. Der Compiler generiert es sowieso als konstante Milliardenzahl.
Wenn Sie über Objective-C sprechen, 1000^3
funktioniert dies nicht, da es keine solche Syntax für pow gibt (es ist xor). Stattdessen kann die pow()
Funktion verwendet werden. In diesem Fall ist es jedoch nicht optimal, sondern ein Laufzeitfunktionsaufruf, keine vom Compiler generierte Konstante.
Betrachten Sie zur Veranschaulichung der Gründe das folgende Testprogramm:
$ cat comma-expr.c && gcc -o comma-expr comma-expr.c && ./comma-expr
#include <stdio.h>
#define BILLION1 (1,000,000,000)
#define BILLION2 (1000^3)
int main()
{
printf("%d, %d\n", BILLION1, BILLION2);
}
0, 1003
$
Eine andere Möglichkeit, einen ähnlichen Effekt in C für Dezimalzahlen zu erzielen, ist die Verwendung der wörtlichen Gleitkommanotation - solange ein Double die gewünschte Zahl ohne Genauigkeitsverlust darstellen kann.
IEEE 644 64-Bit-Double kann problemlos jede nicht negative Ganzzahl <= 2 ^ 53 darstellen. In der Regel kann Long Double (80 oder 128 Bit) sogar noch weiter gehen. Die Konvertierungen werden zur Kompilierungszeit durchgeführt, sodass kein Laufzeitaufwand entsteht und Sie wahrscheinlich Warnungen erhalten, wenn ein unerwarteter Genauigkeitsverlust auftritt und Sie einen guten Compiler haben.
long lots_of_secs = 1e9;
1_000_000_000
. B. in Swift . Mit Zeitkonstanten ist dies jedoch schwieriger. Schreiben ist besser lesbar30 * 60
(30 Minuten in Sekunden) als Schreiben1800
. Es gibt tatsächlich Sprachen, mit denen Sie Einheiten schreiben können, z. B.meters
um sich vor schlechten Aufgaben zu schützen.^
ist ein XOR, kein Exponent oder Power Operator.