Ich bin kürzlich auf diese Programmiersprache gestoßen:
const float Zero = 0.0;
Das wird dann in Vergleichen verwendet:
if (x > Zero) {..}
Kann mir jemand erklären, ob dies wirklich effizienter, lesbarer oder wartbarer ist als:
if (x > 0.0) {..}
HINWEIS: Ich kann mir andere Gründe vorstellen , um diese Konstante zu definieren. Ich frage mich nur, wie sie in diesem Zusammenhang verwendet wird.
x
type vorhanden istfloat
, wird diex > 0.0
Beförderung zu erzwungendouble
, was möglicherweise weniger effizient ist. Das ist kein guter Grund für eine benannte Konstante verwendet allerdings nur für dafür , dass Ihre Konstanten den richtigen Typ haben (zB0f
,float(0)
oderdecltype(x)(0)
).13.37
nichtfloat
, es istdouble
. Also , wenn Sie willfloat
dann war es denkbar Ihr Tutor richtig. In einigen Kontexten (z. B. Zuweisung zu einem Float)13.37
wird implizit in den vonfloat
Ihnen gewünschten konvertiert , in anderen Kontexten (z. B. Abzug von Vorlagentypen) wird dies nicht der Fall sein, während der Datentypstatic const float
immer wie von Ihnen beabsichtigt beginnt. Daher typsicherer. Wohlgemerkt, wäre es auch so13.37f
! Es gibt jedoch noch andere Gründe, das Makro zu vermeiden, als "Typensicherheit". Es ist also genauso wahrscheinlich, dass der Tutor Ihnen ein schlechtes Argument geliefert hat.Antworten:
Mögliche Gründe sind das Zwischenspeichern, Benennen oder Erzwingen des Typs
Caching (nicht zutreffend)
Sie möchten die Kosten für das Erstellen eines Objekts während des Vergleichs vermeiden. In Java wäre ein Beispiel
Dies ist ein ziemlich schwerer Erstellungsprozess und wird mit der bereitgestellten statischen Methode besser bedient:
Auf diese Weise können Vergleiche durchgeführt werden, ohne dass sich die Erstellungskosten wiederholen, da das BigDecimal während der Initialisierung von der JVM vorab zwischengespeichert wird.
Bei dem, was Sie beschrieben haben, führt ein Grundelement denselben Job aus. Dies ist in Bezug auf Caching und Leistung weitgehend überflüssig.
Benennung (unwahrscheinlich)
Der ursprüngliche Entwickler versucht, eine systemweit einheitliche Namenskonvention für gemeinsame Werte bereitzustellen. Dies hat einige Vorzüge, insbesondere bei ungewöhnlichen Werten, aber etwas so grundlegendes wie Null ist es nur im Fall des früheren Caching-Falls wert.
Erzwingender Typ (höchstwahrscheinlich)
Der ursprüngliche Entwickler versucht, einen bestimmten primitiven Typ zu erzwingen, um sicherzustellen, dass Vergleiche auf den richtigen Typ und möglicherweise auf einen bestimmten Maßstab (Anzahl der Dezimalstellen) übertragen werden. Dies ist in Ordnung, aber der einfache Name "Null" ist wahrscheinlich nicht ausreichend detailliert für diesen Anwendungsfall, da ZERO_1DP ein geeigneterer Ausdruck der Absicht ist.
quelle
typedef
von den Variablen den Typ an genau einer Stelle behalten und das Ändern ermöglichen, ohne den Code ändern zu müssen.0.0f
.byteVar1 = byteVar2 Or CB128
scheint ein wenig netter alsbyteVar1 = byteVar2 Or CByte(128)
. Natürlich wäre es noch besser, ein richtiges numerisches Suffix für Bytes zu haben. Da C # die Operanden von bitweisen zu Operatoren befördert,int
selbst wenn das Ergebnis garantiert in ein passtbyte
, ist das Problem dort nicht so relevant.Es ist wegen "Tooling Nagging"
Ein möglicher Grund, warum ich hier nicht aufgeführt sehe, ist, dass viele Qualitätswerkzeuge die Verwendung von magischen Zahlen kennzeichnen . Es ist oft eine schlechte Praxis, magische Zahlen in einen Algorithmus zu werfen, ohne sie für spätere Änderungen deutlich sichtbar zu machen, insbesondere wenn sie an mehreren Stellen im Code dupliziert werden.
Diese Tools kennzeichnen solche Probleme zwar zu Recht, führen jedoch häufig zu Fehlalarmen in Situationen, in denen diese Werte harmlos sind und höchstwahrscheinlich statisch oder nur Initialisierungswerte sind.
Und wenn das passiert, haben Sie manchmal die Wahl zwischen:
Über Leistung
Es hängt von der Sprache ab, die ich vermute, aber dies ist in Java ziemlich häufig und hat keine Auswirkungen auf die Leistung, da die Werte zur Kompilierungszeit inline sind, wenn es sich um echte Konstanten handelt
static final
. In C oder C ++ hätte dies keine Auswirkungen, wenn sie entweder als Konstanten oder sogar als Pre-Prozessor-Makros deklariert würden.quelle
Dies kann sinnvoll sein, da explizit definiert wird
Zero
, dass es sich um einen Typ handeltfloat
.Zumindest in C und C ++ ist der Wert
0.0
vom Typdouble
, während das Äquivalentfloat
ist0.0f
. Esx
ist also immer einfloat
Sprichwort, vorausgesetzt, man vergleicht mitwährend tatsächlich zu fördern
x
,double
um die Art,0.0
die zu Problemen führen könnte (mit Gleichheitstests vor allem) zu entsprechen. Der Vergleich ohne Umrechnung wäre natürlichwas dasselbe macht wie
Trotzdem halte ich es für viel nützlicher, Warnungen vor Konvertierungen im Compiler zu aktivieren, anstatt dass Benutzer umständlichen Code schreiben.
quelle
Zunächst wird hier Null definiert als
float
, nichtint
. Dies hat natürlich keine Auswirkung auf den Vergleich. In anderen Fällen kann es jedoch zu Unterschieden kommen, wenn diese Konstante verwendet wird.Ich sehe keinen anderen Grund, warum
Zero
hier eine Konstante deklariert wird. Es ist nur ein Codierungsstil, und es ist besser, dem Stil zu folgen, wenn er überall in diesem bestimmten Programm verwendet wird.quelle
Es ist mit ziemlicher Sicherheit während der Ausführung genauso effizient (es sei denn, Ihr Compiler ist sehr primitiv) und während der Kompilierung etwas weniger effizient.
Was die Frage betrifft, ob das lesbarer ist als
x > 0
... Denken Sie daran, dass es Menschen gibt, die COBOL ehrlich und aufrichtig für eine großartige Idee und eine Freude bei der Arbeit halten es gibt sogar einige Programmierer mit der gleichen Meinung über C ++!) Mit anderen Worten, Sie werden sich in diesem Punkt nicht einig werden, und es lohnt sich wahrscheinlich nicht, darüber zu streiten.quelle
Wenn Sie generischen (dh nicht typspezifischen) Code geschrieben haben, dann sehr wahrscheinlich. Eine
zero()
Funktion kann für jeden algebraischen Typ oder für jeden Typ gelten, bei dem es sich um eine Gruppenaddition handelt. Es könnte eine ganze Zahl sein, es könnte ein Gleitkommawert sein, es könnte sogar eine Funktion sein, wenn Ihre Variable beispielsweise selbst eine Funktion innerhalb eines linearen Raums ist (z. B. ist x eine lineare Funktion der Form z -> a_x * z + b_x) undzero()
liefert dann die Funktion, wobei a und b beidezero()
vom zugrunde liegenden Typ sind.Man würde also einen solchen Code beispielsweise in C ++ (obwohl ein
zero()
AFAIK nicht sehr verbreitet ist) oder in Julia und vielleicht in anderen Sprachen erwarten .quelle