Warum 1.000.000.000 als 1000*1000*1000 in C schreiben?

Lesezeit: 8 Minuten

Ducks Benutzeravatar
Ente

In von Apple erstelltem Code gibt es diese Zeile:

CMTimeMakeWithSeconds( newDurationSeconds, 1000*1000*1000 )

Gibt es einen Grund zu äußern 1,000,000,000 wie 1000*1000*1000?

Warum nicht 1000^3 dafür?

  • Klarheit und Lesbarkeit des Codes. Sie können , oder ‘ nicht als Trennzeichen in C einsetzen, also ist das Nächstbeste, den Wert aus einer Multiplikation zu berechnen. ^ ist ein unabhängiger Operator in C – exklusives ODER.

    – Ich werde nicht existieren Ich werde nicht existieren

    16. November 2016 um 13:21 Uhr

  • Es wird besonders für Zeiträume wie 2 * 60 * 60 verwendet. Es ist leicht zu bemerken, dass dies für 2 Stunden gilt.

    – Idali

    16. November 2016 um 14:41 Uhr

  • Zum einen vermute ich, dass 1.000.000.000 keine gültige Syntax ist

    – Paparazzo

    16. November 2016 um 15:18 Uhr

  • Übrigens haben moderne Programmiersprachen alternative Möglichkeiten, dasselbe zu schreiben, zB in Swift 1_000_000_000. Bei Zeitkonstanten ist dies jedoch schwieriger. Es ist besser lesbar zu schreiben 30 * 60 (30 Minuten in Sekunden) als zu schreiben 1800. Es gibt tatsächlich Sprachen, mit denen Sie Einheiten schreiben können, z meterswodurch Sie sich vor Fehlzuweisungen schützen können.

    – Sulthan

    16. November 2016 um 16:05 Uhr


  • ^ ist ein XOR, kein Exponent oder Potenzoperator.

    – 3Dave

    16. November 2016 um 18:35 Uhr


Benutzeravatar von Piotr Falkowski
Piotr Falkowski

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 nachgedacht hat.

Bedenken Sie:

double memoryBytes = 1024 * 1024 * 1024;

Es ist eindeutig besser als:

double memoryBytes = 1073741824;

da letzteres auf den ersten Blick nicht wie die dritte Potenz von 1024 aussieht.

Wie Amin Negm-Awad erwähnte, die ^ Operator ist die Binärzahl XOR. Vielen Sprachen fehlt der eingebaute Potenzierungsoperator zur Kompilierzeit, daher die Multiplikation.

  • Und in Sprachen, die einen Exponentiationsoperator haben, ist es nicht unbedingt ‘^’. In Fortran ist es zum Beispiel ‘**’.

    – jamesqf

    16. November 2016 um 17:28 Uhr

  • Sie sollten auch einen Link hinzufügen, der auf den wichtigen Vorbehalt verweist, der unten in der Antwort angegeben ist, von @chux: stackoverflow.com/a/40637622/1841533 (insbesondere da das OP mit dem Tag „c“ gekennzeichnet ist, das sehr anfällig für diese „rechte Hand“ ist Bei Nebenoperationen scheinen alle Terme auf einen kleineren Typ beschränkt zu sein, und daher kann das Problem der Multiplikation überlaufen). securecoding.cert.org/confluence/display/c/… kann helfen, diese im allgemeinen Fall zu vermeiden?

    – Olivier Dulac

    16. November 2016 um 18:13 Uhr


  • Außerdem sollten wir beachten, dass die Berechnung zur Kompilierzeit erfolgt. Der C-Standard erfordert, dass die Implementierung konstante Ausdrücke zur Kompilierzeit für verschiedene Funktionen der Sprache berechnen kann, und wir können davon ausgehen, dass dies zutrifft, wenn ein konstanter Ausdruck wie in diesem Beispiel verwendet wird.

    – au

    16. November 2016 um 18:32 Uhr

  • Speichermenge doppelt speichern? Das scheint eine mögliche Fehlerquelle zu sein.

    – JAB

    16. November 2016 um 19:25 Uhr


  • @supercat Das ist mir bewusst, aber wenn Sie double verwenden, könnten Sie einen Fall haben, in dem Sie beispielsweise einen Teil des Speicherbereichs möchten, durch den Sie dividieren x um die Größe des Unterbereichs zu erhalten … und plötzlich haben Sie ein Bruchbyte, für das möglicherweise zusätzliche Logik erforderlich ist, um dies zu kompensieren.

    – JAB

    17. November 2016 um 0:00 Uhr


chux – Stellt Monicas Benutzeravatar wieder her
Chux – Wiedereinsetzung von Monica

Es gibt Gründe nicht benutzen 1000 * 1000 * 1000.

Mit 16bit int, 1000 * 1000 überläuft. Also verwenden 1000 * 1000 * 1000 verringert die Portabilität.

Mit 32bit intläuft 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 dem Typ des Ziels für Lesbarkeit und Portabilität entspricht und Richtigkeit.

double Duration = 1000.0 * 1000 * 1000;
long long Duration = 1000LL * 1000 * 1000 * 1000;

Auch Code könnte einfach verwendet werden e Notation für Werte, die exakt als a darstellbar sind double. Dies führt natürlich zu dem Wissen, ob double genau den ganzzahligen Wert darstellen kann – was bei Werten größer als 1e9 bedenklich ist. (Sehen DBL_EPSILON und DBL_DIG).

long Duration = 1000000000;
// vs.
long Duration = 1e9;

  • Sehr wichtiger Hinweis! securecoding.cert.org/confluence/display/c/… kann in vielen Fällen helfen?

    – Olivier Dulac

    16. November 2016 um 18:18 Uhr

  • EIN double kann alle ganzen Zahlen bis 2^53 ≈ 9e15 genau darstellen.

    – Edgar Bonett

    17. November 2016 um 9:56 Uhr

  • @EdgarBonet Das stimmt binär64 kann ganze Zahlen bis etwa 9e15 darstellen. Aber C gibt nicht an double Verwendung von binary64, 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 die gängige Praxis verlassen möchten.

    – chux – Wiedereinsetzung von Monica

    17. November 2016 um 15:14 Uhr


  • @Patrick Beide 1000 und 1000000000000 sind ganzzahlige Konstanten. Jeder hat unabhängig voneinander den Typ ausgewählt aus int, long oder long long. Der Compiler verwendet den ersten Typ dieser 3, in denen die ganzzahlige Konstante passt. 1000 * 1000 * 1000 * 1000 ist damit fertig int Mathe wie jeder 1000 in einem (n int. Das Produkt läuft mit 32-Bit über int. 1000000000000 ist durchaus darstellbar als long long (oder möglicherweise schmaler) – kein Überlauf. Der Typ des Ziels long long Duration wirkt sich nicht auf diese “rechte Seite der =”-Bestimmung aus.

    – chux – Wiedereinsetzung von Monica

    17. November 2016 um 18:25 Uhr

  • Es ist wichtig, den breiteren Typ bei der Multiplikation an erster Stelle zu setzen. Mit 16bit int, long x = 1000 * 1000 * 1000L; würde überlaufen, während long x = 1000L * 1000 * 1000; würde nicht.

    – ad absurdum

    24. Juli 2017 um 15:03 Uhr

Benutzeravatar von Amin Negm-Awad
Amin Negm-Awad

Warum nicht 1000^3?

Das Ergebnis von 1000^3 ist 1003. ^ ist der Bit-XOR-Operator.

Auch wenn es sich nicht um das Q selbst handelt, füge ich eine Klarstellung hinzu. x^y tut nicht immer auswerten x+y wie es im Beispiel des Fragestellers der Fall ist. Sie müssen jedes Bit xor. Im Fall des Beispiels:

1111101000₂ (1000₁₀)
0000000011₂ (3₁₀)
1111101011₂ (1003₁₀)

Aber

1111101001₂ (1001₁₀)
0000000011₂ (3₁₀)
1111101010₂ (1002₁₀)

  • Sir, mir ist nicht klar, wie 1003 ^ 3 1003 ist. Der Google- und Mac-Rechner zeigt 1000 ^ 3 = 1.000.000.000. können Sie erklären?

    – MD.

    16. November 2016 um 13:23 Uhr

  • Das ^ Operator bedeutet XOR in C/C++/Objective-C usw. In Taschenrechnern bedeutet es normalerweise x-to-y-Potenz.

    – Tamás Zahola

    16. November 2016 um 13:25 Uhr

  • Bah, die Bits von 1000 und 3 überlappen sich nicht. Das sieht aus Also falsch.

    – Yakk – Adam Nevraumont

    16. November 2016 um 16:40 Uhr

  • Die Bits überlappen sich. Aber nicht die 1er. 🙂

    – Amin Negm-Awad

    16. November 2016 um 16:45 Uhr

  • @ Yakk: in der Tat sieht es so falsch aus! … Ich hoffe, viele Leute werden nicht denken, dass “A ^ B” immer A + B ergibt (aber ich fürchte, einige könnten …)

    – Olivier Dulac

    16. November 2016 um 18:10 Uhr


Zur Lesbarkeit.

Kommas und Leerzeichen zwischen die Nullen setzen (1 000 000 000 oder 1,000,000,000) würde einen Syntaxfehler erzeugen, und mit 1000000000 im Code macht es schwierig, genau zu sehen, wie viele Nullen es gibt.

1000*1000*1000 macht deutlich, dass es 10^9 sind, weil unsere Augen die Brocken leichter verarbeiten können. Außerdem entstehen keine Laufzeitkosten, da der Compiler sie durch die Konstante ersetzt 1000000000.

Benutzeravatar von djechlin
Djechlin

Zur Lesbarkeit. Zum Vergleich unterstützt Java _ in Zahlen, um die Lesbarkeit zu verbessern (zuerst vorgeschlagen von Stephen Colebourne als a Antwort auf Derek Fosters VORSCHLAG: Binäre Literale für Project Coin/JSR 334) . Man würde schreiben 1_000_000_000 hier.

In ungefähr chronologischer Reihenfolge, von der ältesten Unterstützung zur neuesten:

Es ist ein relativ neues Feature für Sprachen zu erkennen, dass sie es unterstützen sollten (und dann ist da noch Perl). Wie in der ausgezeichneten Antwort von [email protected], 1000*1000... ist eine Teillösung, öffnet den Programmierer jedoch Fehlern durch Überlaufen der Multiplikation, selbst wenn das Endergebnis ein großer Typ ist.

  • Viele moderne Programmiersprachen haben das gleiche, zB Swift. Nichts Neues.

    – Sulthan

    16. November 2016 um 16:06 Uhr

  • AFAIK, das kommt von Perl. PL/M benutzte $ für denselben Zweck, zB: 0100$0010B

    – ninjalj

    17. November 2016 um 0:52 Uhr

  • Es ist allerdings ziemlich neu. Das Java-Feature ist vielleicht 5 Jahre alt. Die meisten anderen Sprachen, die diese Syntax unterstützen, sind ziemlich neu – Swift selbst ist erst ein paar Jahre alt. Python fügt Unterstützung in 3.6 hinzu, das noch nicht veröffentlicht wurde.

    – johncip

    17. November 2016 um 3:02 Uhr

  • Ada unterstützt seit 33 Jahren Unterstreichungen in Integer-Literalen.

    – Peter – Setzen Sie Monica wieder ein

    17. November 2016 um 10:02 Uhr


  • @djechlin: Ich habe mir erlaubt, weitere Informationen hinzuzufügen, ungefähr in chronologischer Reihenfolge. Ich habe mich vorher geirrt, nach dem Project Coin-Thread zu urteilen, hat Stephen Colebourne wahrscheinlich die Idee des Unterstrichs in Integer-Literalen von Fandom und/oder Ruby übernommen. Ruby hat die Idee wahrscheinlich von Perl und Perl von Ada übernommen.

    – ninjalj

    17. November 2016 um 19:27 Uhr

Benutzeravatar von Bista
Bista

Könnte einfacher zu lesen sein und einige Assoziationen mit dem bekommen 1,000,000,000 bilden.

Aus technischer Sicht gibt es meiner Meinung nach keinen Unterschied zwischen der direkten Zahl oder der Multiplikation. Der Compiler generiert es sowieso als konstante Milliardenzahl.

Wenn Sie von Objective-C sprechen, dann 1000^3 funktioniert nicht, weil es keine solche Syntax für pow gibt (es ist xor). Stattdessen, pow() Funktion genutzt werden kann. In diesem Fall ist es jedoch nicht optimal, es handelt sich um einen Laufzeitfunktionsaufruf, nicht um eine vom Compiler generierte Konstante.

  • Viele moderne Programmiersprachen haben das gleiche, zB Swift. Nichts Neues.

    – Sulthan

    16. November 2016 um 16:06 Uhr

  • AFAIK, das kommt von Perl. PL/M benutzte $ für denselben Zweck, zB: 0100$0010B

    – ninjalj

    17. November 2016 um 0:52 Uhr

  • Es ist allerdings ziemlich neu. Das Java-Feature ist vielleicht 5 Jahre alt. Die meisten anderen Sprachen, die diese Syntax unterstützen, sind ziemlich neu – Swift selbst ist erst ein paar Jahre alt. Python fügt Unterstützung in 3.6 hinzu, das noch nicht veröffentlicht wurde.

    – johncip

    17. November 2016 um 3:02 Uhr

  • Ada unterstützt seit 33 Jahren Unterstreichungen in Integer-Literalen.

    – Peter – Setzen Sie Monica wieder ein

    17. November 2016 um 10:02 Uhr


  • @djechlin: Ich habe mir erlaubt, weitere Informationen hinzuzufügen, ungefähr in chronologischer Reihenfolge. Ich habe mich vorher geirrt, nach dem Project Coin-Thread zu urteilen, hat Stephen Colebourne wahrscheinlich die Idee des Unterstrichs in Integer-Literalen von Fandom und/oder Ruby übernommen. Ruby hat die Idee wahrscheinlich von Perl und Perl von Ada übernommen.

    – ninjalj

    17. November 2016 um 19:27 Uhr

Peter - Stellen Sie Monicas Benutzeravatar wieder her
Peter – Wiedereinsetzung von Monica

Um die Gründe zu veranschaulichen, betrachten Sie 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
$

  • @pjvandehaar Ich würde nicht empfehlen, eine Sprache durch das Lesen von Wikipedia-Artikeln zu lernen.

    – Peter – Setzen Sie Monica wieder ein

    3. Dezember 2016 um 9:04 Uhr


1424050cookie-checkWarum 1.000.000.000 als 1000*1000*1000 in C schreiben?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy