Ist es in Sprachen, die keine Unterstriche in ganzzahligen Literalen zulassen , eine gute Idee, eine Konstante für 1 Milliarde zu erstellen? zB in C ++:
size_t ONE_BILLION = 1000000000;
Sicherlich sollten wir keine Konstanten für kleine Zahlen wie 100 erstellen. Bei 9 Nullen ist es jedoch wahrscheinlich einfach, eine Null wegzulassen oder eine zusätzliche Eins im Code wie folgt hinzuzufügen:
tv_sec = timeInNanosec / 1000000000;
tv_nsec = timeInNanosec % 1000000000;
coding-style
Martin C. Martin
quelle
quelle
1e9
, ob Sie schreiben möchten10^9
oder1_000_000_000
ob die von Ihnen verwendete Sprache dies unterstützt.Antworten:
Die meisten Sprachen haben eine Art Exponentialnotation. Eine Million ist
1e6
, (was 1 mal 10 hoch 6 bedeutet). Dies löst das Problem im Grunde noch besser als die meisten Vorschläge hier.In vielen C-ähnlichen Sprachen definiert die wissenschaftliche Notation jedoch einen Gleitkommatyp , was unglücklich ist, wenn Sie wirklich ein int benötigen. Sie können diese Konstante jedoch leicht tippen, um implizite Konvertierungen in Ihrem Formular zu vermeiden.
n / int(1e9)
würde durch eine Milliarde teilen.In Ihrem Beispiel, das sich mit physikalischen Größen (Zeit in Nanosekunden) befasst, würde ich mich generell fragen, ob eine Ganzzahl der richtige Typ ist. Tatsächlich ist ein Gleitkomma
double
möglicherweise besser geeignet, um mit messbaren Größen umzugehen (obwohl es natürlich Fälle gibt, in denen Sie a vorziehen würdenlong long
).quelle
long long
Bereich verwenden.Erstellen Sie stattdessen eine mit dem Namen NANOSECONDS_IN_ONE_SECOND als das, was sie darstellt.
Oder ein kürzerer, besserer Name, wenn Sie sich einen vorstellen können.
quelle
Nanoseconds_Per_Second
aber dies ist meiner Meinung nach die richtige Antwort.NANOSECONDS
ja , ist eine Konstante namens bedeutungslos, da Sie nicht sagen können, worauf sie angewendet werden soll. EbensoNANOSECONDS_PER_MICROSECOND
ist eine ähnliche gültige Konstante sinnvoll.1mm/1m = 1000
, Das ist genau der Punkt , von dem, was hier getan wird.NS_PER_SEC
sollte jedem klar sein, der es mit Nanosekunden zu tun haben sollte.Konstanten sollen Zahlen einen Sinn geben. Es gibt keine zusätzliche Bedeutung in
ONE_BILLION
zu1000000000
. Tatsächlich ist es verwirrender, denn in verschiedenen natürlichen Sprachen bedeutet eine Milliarde etwas anderes (entweder eine Milliarde oder eine Million)! Wenn Sie es kürzer schreiben möchten, gibt es eine gute Chance, dass Ihre Programmiersprache die Verwendung der wissenschaftlichen Notation ermöglicht, dh1e9
. Ansonsten stimme ich @JohnB zu, dass diese Zahl wirklich die Anzahl der Nanosekunden pro Sekunde bedeutet.quelle
Für ein oder zwei Verwendungen würde ich die Konvention verwenden:
Es ist vollkommen selbsterklärend, wird zu einer Konstanten kompiliert und es ist schwer zu vermasseln.
Es ist auch sehr nützlich in Fällen wie:
Wo es leicht zu sehen ist, reden wir über einen Tag in Sekunden.
quelle
instance.Time = ...
, aber dann habe ich es niedergeschlagen ...(1000 * 1000 * 1000)
ist es vom Typint
, der nur 16 Bit haben muss, damit er überlaufen kann. Sie können schreiben(1000L * 1000L * 1000L)
, um das zu vermeiden.Die Länge des Werts bestimmt nicht, ob eine Konstante benötigt wird oder nicht.
Sie verwenden Konstanten, um magische Zahlen zu vermeiden, und nicht, um das Tippen zu vermeiden.
Zum Beispiel sind dies vollkommen gültige Konstanten:
Verwenden:
(Codebeispiele sind in Java und werden in Ihre Lieblingssprache übersetzt.)
quelle
Eine amerikanische oder europäische Milliarde?
(oder in technischer Hinsicht eine Milliarde im kurzen oder im langen Maßstab - eine ist 1000 Millionen, die andere ist eine Million Millionen).
In Anbetracht dieser Verwirrung würde ich ja sagen - es ist sinnvoll, es einmal zu definieren und dabei zu bleiben. Dies gilt auch für alle Konstanten, bei denen Sie sich auf die Definition einigen müssen - definieren Sie es einmal.
quelle
Gründe, nicht zu
Erstens gibt es hier einen Grund, keine Unterstriche zu schreiben oder einen Trick zu verwenden, um dies zu simulieren: Es erschwert das Auffinden der Konstanten im Code. Angenommen, ein Programm weist irgendwo in seiner Operation einen fest codierten Wert von 1500000 für einen Parameter auf. Ich möchte wissen, wo im Quellcode des Programms dies tatsächlich vorkommt, also greife ich nach dem Code
1500000
und finde nichts. Warum? Könnte es hexadezimal sein (aber warum für eine solche runde Dezimalzahl). Mir ist nicht bekannt, dass die Konstante tatsächlich so geschrieben ist1_500_000
. Ich brauchte den Regex1_?500_?000
.Leitfiguren im Kommentar
Nur weil eine Art von visueller Hilfe nicht verfügbar ist oder wir sie aus dem oben genannten Grund nicht verwenden möchten, bedeutet dies nicht, dass wir die beiden Dimensionen der Textdatei nicht nutzen können, um eine alternative visuelle Hilfe zu erstellen:
Damit können wir uns leicht davon überzeugen, dass es drei Gruppen von drei Nullen gibt. Trotzdem können wir den Quellcode durchsuchen
1000000000
und finden.Syntax-Färbung
Ein Texteditor mit programmierbarer Syntaxfärbung kann zur besseren Lesbarkeit in numerischen Konstanten mit alternierenden Farben in Farbgruppen eingeteilt werden. Wir müssen nichts im Code tun.
Vorverarbeitung: C, C ++, Ziel C
Wenn wir nun wirklich Kommas zwischen Ziffern wollen, können wir in C und C ++ eine Vorverarbeitung verwenden:
Funktioniert für Zahlen wie
TH(1,234,567,890)
.Ein TH-ähnliches Makro kann auch mit Token-Einfügen anstelle von Arithmetik arbeiten. Im C-Präprozessor kann der Binäroperator
##
("Token Paste") in einem Makrotext verwendet werden, um zwei Operanden zu einem einzigen Token zusammenzufügen. Einer oder beide Operanden können Makroargumente sein. Der Nachteil hier (was ein Risiko für uns darstellt) ist, dass das Verhalten undefiniert ist, wenn die resultierende Verkettung kein gültiges Token ist.Jetzt
C-Programme, die Bezeichner zusammenfügen und die Ergebnisse verwenden, um globale Variablen und Funktionen zu benennen, existieren und sind schrecklich zu bearbeiten, da sie für Tools wie GNU-ID-Utils und -Ctags undurchlässig sind.
quelle
Ja, das klingt nach einer vernünftigen Idee. Off-by-One-DIGIT-Fehler sind noch schlimmer als die berüchtigten Off-by-One-Fehler. Es kann jedoch Verwirrung stiften, wenn andere Personen (einschließlich Ihres zukünftigen Selbst) den Code lesen.
Ein erklärenderer Name wie NANOSEC_PER_SEC scheint gut zu sein, da er Klarheit darüber verschafft, wo er für die Zeit verwendet wird. Die Verwendung in anderen Kontexten als der Zeit ist jedoch nicht sinnvoll und es wäre unpraktisch, für jede Situation eine separate 1.000.000.000 zu erstellen.
Was Sie wirklich tun möchten, so albern es zunächst aussieht, ist "Teilung über Sekunde". Dadurch bleibt NANO_PER erhalten, das nicht nur sprachunabhängig ist (10 ^ 9 in Amerika und Europa), sondern auch situationsunabhängig (keine Beschränkung der Einheiten), und es ist einfach zu tippen und zu lesen.
quelle
Im Allgemeinen ist es eine schlechte Idee, skalare Konstanten für Einheitenumrechnungen zu verwenden, und wenn Sie Konstanten für solche Dinge erstellen, führen Sie die Umrechnung an viel zu vielen Stellen durch.
Wenn Sie eine Größe von einer Einheit (z. B. 10 Sekunden) haben und in eine andere Einheit (z. B. Nanosekunden) umrechnen möchten; Dies ist genau der Zeitpunkt, um das Typensystem Ihrer Sprache zu verwenden und sicherzustellen, dass die Einheiten tatsächlich so skaliert werden, wie Sie es beabsichtigen.
Machen Sie Ihre Funktion einen nehmen
Nanoseconds
Parameter und liefern Umwandlung Betreiber und / oder Konstrukteuren in dieser Klasse fürSeconds
,Minutes
oder was-haben-Sie. Dies ist, wo Ihreconst int
oder#define
oder1e9
in anderen Antworten gesehen gehört.Dadurch wird vermieden, dass Variablen mehrdeutiger Einheiten in Ihrem Code schweben. und verhindert ganze Schwaden von Fehlern, bei denen die falsche Multiplikation / Division angewendet wurde oder bereits angewendet wurde oder die Menge tatsächlich Abstand statt Zeit war, oder ...
In solchen Klassen empfiehlt es sich außerdem, eine Konstruktion aus einfachem Skalarsprivate zu erstellen und ein statisches "MakeSeconds (int)" oder ähnliches zu verwenden, um die unbeholfene Verwendung undurchsichtiger Zahlen zu unterbinden.
In C ++ können Sie Boost.Chrono genauer untersuchen .
quelle
Ich persönlich halte es nicht für eine gute Praxis, eine Konstante zu erstellen, es sei denn, es muss eine Konstante sein. Wenn es sich an mehreren Stellen befindet und oben in der Datei definiert ist, um es zu ändern oder zu testen, ist es absolut nützlich.
Wenn es nur weil es umständlich zu tippen ist? dann nein.
Persönlich, wenn ich den Code einer anderen Person habe, für den eine Konstante definiert ist, halte ich dies im Allgemeinen für einen wichtigen Aspekt des Codes. ZB tcp Keep Alive Timer, maximal zulässige Anzahl von Verbindungen. Wenn ich es debuggen müsste, würde ich wahrscheinlich viel unnötige Aufmerksamkeit darauf richten, um herauszufinden, warum / wo es verwendet wird.
quelle
Wenn Sie darüber nachdenken, warum Sie in Ihrem Fragentitel "1 Milliarde" anstelle von "1000000000" geschrieben haben, werden Sie feststellen, warum die Antwort "Ja" lautet.
quelle
Erstellen Sie keine Konstante für Ihre großen Literale. Für jedes dieser Wörter braucht man eine Konstante, was meiner Meinung nach ein Witz ist. Wenn Sie Ihre Literale unbedingt ohne die Hilfe von Syntaxhervorhebungen klarer machen müssen, können Sie (obwohl ich es nicht tun würde) Funktionen oder Makros erstellen, um Ihr Leben "einfacher" zu machen:
quelle
Ich würde das machen:
oder
const int
SciMega = 1000 * 1000; const intSciGiga = 1000 *SciMega;In Bezug auf die Anzahl der Nanosekunden pro Sekunde: Nano ist die "Inverse" von Giga.
Beachten Sie das "Sci" - für wissenschaftliche Zwecke sind die Bedeutungen von Kilo, Mega, Giga usw. unterschiedlich: 1024 (2 ^ 10), 1024 * 1024 (2 ^ 20) usw. 2 Megabyte sind nicht 2.000.000 Bytes .UPDATE Commenter wies darauf hin, dass für digitale Exponenten von 2 spezielle Begriffe existieren: http://en.wikipedia.org/wiki/Mebibyte
quelle