Macht es Sinn die Einheit in den Variablennamen zu integrieren?
uint64_t frequency_is_1Hz;
anstatt
uint64_t frequency_is;
Oder anderes Beispiel, wo der Nutzen noch offensichtlicher wird:
uint32_t temperature_case_0C1;
Wie denkt ihr darüber?
Wenn man mit Ländern mit imperialen Einheiten zusammenarbeitet sicher.
Sonst geben die das noch in sqft*oz/psi an…
Allgemein würde ich aber in Basiseinheiten rechnen und die Einheit im
Kommentar angeben.
Wenn es sinnvoll ist, ja, wenn nicht, dann nicht. Das gilt eigentlich
für alle Variablennamen...
Wobei C++ zum Handling von solchen physikalischen Größen mit
unterschiedlichen Einheiten benutzerdefinierte Literale bietet, die da
sehr viel Sicherheit reinbringen. Aussagekräftige Variablennamen kann
man dazu dann immer noch nutzen.
Oliver
Bei einer Frequnez würde ich von Hz ausgehen, wenn nichts andere dran
steht. bei Zeitspannen macht das eher Sinn:
duration_ms
timeout_minutes
Oder auch:
price_cent
Mir persönlich genügt es, wenn das in einem Kommentar direkt über der
Variable bzw. Funktion (bei Parametern) dokumentiert ist.
Anonymous U. schrieb:> Macht es Sinn die Einheit in den Variablennamen zu integrieren?
Nein.
Definiere Dir dafür eigene Datentypen. Es gibt genug Beispiele für die
Modellierung physikalischer Einheiten im Netz.
Anonymous U. schrieb:> Wie denkt ihr darüber?
Ich sage, denke und handle ....
Variablen immer klein beginnen.
KamelHöckerSchreibweise
Keine Unterstriche
Keine ungarische Notation (noch nicht mal in deiner abgeschwächten
Version)
Geltungsbereich so weit wie irgend möglich einschränken.
Oliver S. schrieb:> benutzerdefinierte Literale
Ja!
Beispiel(aus meiner kleinen Arduino Welt):
Wenn Du mehrere Formate für Frequenz hast, dann mache einen Typ daraus.
Bei nur einem wäre es dumm, da es keine Info birgt und das über den Code
verteilt wird.
Bei mehreren wäre es unzureichend, da Du ja unterschiedliche Funktionen
damit aufrufen musst.
Anonymous U. schrieb:> Wie denkt ihr darüber?
Beide verstehe ich nicht.
Eine Frequenz f in Hz könnte in einer Variablen namens frequency_Hz
stecken.
Aber das frequency_is_1Hz bedeuten soll ? Ein boolscher Wert der nur
dann tru ist wenn die Frequenz genau 1 Hz beträgt ?
Und temperature_case_0C1 soll 0C1 etwa 0,1 GradC bedeuten ? Wenn man die
Temperatur mit Nachkommastellen erfasst, dann
temp_Zehntelgrad oder temp_tenthsofadegreecelsius
Also im Prinzip sinnvoll, aber eindeutiger gewählte Namen sonst weiss es
der andere Leser doch wieder nicht.
Wilhelm M. schrieb:> Anonymous U. schrieb:>> Macht es Sinn die Einheit in den Variablennamen zu integrieren?>> Nein.>> Definiere Dir dafür eigene Datentypen. Es gibt genug Beispiele für die> Modellierung physikalischer Einheiten im Netz.
Ich bin ja erstaunt, dass ich hier nicht mit negativen Kommentaren
beworfen worden bin. Habe ich doch vor ca. 3-4 Jahren noch dafür
tiefsten Spott erhalten. Manche Dinge scheinen sich ja so langsam
einzuschleifen ...
Für jemanden, der da weder in noch up signen will, ist der Link nutzlos.
Macht aber nichts, wer will, findet beliebig andere, die frei zugänglich
sind.
Oliver
Edit: im zweiten Anlauf geht es. Aber trotzdem:
https://en.cppreference.com/w/cpp/language/user_literal
@ Anonymous U.
Ich denke, Deine eigenen Ansichten sind da der Maßstab. Falls Du Dir in
einem konkreten Projekt Fälle vorstellen kannst, in denen Dir das von
Nutzen ist, mach es so.
Oliver S. schrieb:> Für jemanden, der da weder in noch up signen will, ist der Link nutzlos.
Ich muss mich dort nicht Anmelden. Blockiere mal JS auf der Webseite
(z.B.: mit uMatrix, NoScript).
Würde ich nicht machen. Das macht den Code wahnsinnig unleserlich.
Einfach beim Anmelden der Variablen bzw. bei der Definition des
Datentyps per Kommentar das dokumentieren, was man wissen muss. In einem
Kommentar hat man den Platz dafür und eben einen Ort wo man nachschauen
kann. Das reicht völlig. Eine Variable muss mir nicht an jeder Stelle im
Code, wo Sie steht, ihre Einheit im Namen entgegen plärren. Das ist
redundante Information. Und je nach Variable bzw. Anwendung sind Dinge
wie die physikalische Einheit, Wert eines LSB, Wertebereich,
Vorzeichenkonvention, etc. von Interesse. Das kann man u. U. unmöglich
alles sinnvoll in einen Variablennamen packen.
Jetzt mal von eher ausgefallenen Einheiten ganz zu schweigen... Mir
fällt jetzt spontan nur "nV/sqrt(Hz)" ein, aber ich denke es ist klar
was ich meine.
MaWin schrieb:> Aber das frequency_is_1Hz bedeuten soll ? Ein boolscher Wert der nur> dann tru ist wenn die Frequenz genau 1 Hz beträgt ?
Sowas gibts bei mir nur als Makros und da machts auch Sinn.
frequency_Hz das gibts bei mir gern in Variablen.
Ein 50 Jahre altes Zitat, mit dem Dimensionen/Einheiten aus
Programmiersprachen herausgehalten wurden:
"“Numbers as invented by mathematicians are abstract and beautiful. This
should not be spoiled by engineers".
Ich benutze meistens SI-Einheiten, dann ist klar, was z.B. unter
BusSpannung gespeichert wird.
Muss ich die allerdings anders abspeichern, weil z.B Millivolt und
Megahertz gespeichert werden, dann gebe ich die Einheit auch bei den
Variablennamen an:
BusSpannungmV
CpuFrequenzMhz
Das kennzeichnet dann, dass die Einheit nicht die 'normale' Si-Einheit
ist.
Damit lebe ich seit mehreren Jahren ganz gut.
Wenn irgendwie möglich, wähle ich als Einheit für Variablen immer die
entsprechende kohärente SI-Einheit. Dies muss dann genau einmal für ein
ein gesamtes Softwareprojekt als kurzer Vermerk dokumentiert werden. Bei
Verwendung von FP-Datentypen geht das praktisch immer.
Verwendet man aus Effizienzgründen Integertypen, möchte man oft die
Zahlenwerte skalieren, um entweder die Auflösung oder den Wertebereich
zu vergrößern. Da versuche ich dann, mit möglichst wenigen verschiedenen
Skalierungsfaktoren auszukommen, idealerweise mit maximal zwei pro
physikalischer Größe und Programmmodul (Bibliothek, Übersetzungseinheit
oder Klasse): Einen für das API und optional einen davon abweichenden
für die interne Darstellung. Beides wird an zentraler Stelle für das
jeweilige Modul dokumentiert.
Eine Dokumentation des Skalierungsfaktors für jede Einzelvariable ist
damit nicht erforderlich.
Nur in Ausnahmefällen, wo aus triftigen Gründen der Skalierungsfaktor
einer Variable von der programm- oder modulweit festgelegten Vorgabe
abweichen muss, dokumentiere ich diesen Umstand gesondert für die
entsprechende Variable, bspw. im Kommentar bei der Deklaration. Das es
sich hier um einen Ausnahmefall handelt, der besonderes Augenmerk
verdient, kann es aber auch sinnvoll sein, dem Variablennamen einen
entsprechenden Suffix anzuhängen, bspw. "duration_ms", "delay_ticks",
"distance_100m" oder "angle_2piDiv256". Der Unterstrich ist dabei als
"in" zu lesen.
Die Verwendung von benutzerdefinierten Literalen und größenspezifischen
Datentypen (bspw. Boost.Units) kann bei komplexen physikalischen
Berechnungen bei der Fehlervermeidung hilfreich sein, ist aber ein
Thema, das nur indirekt mit der Fragestellung des TE zu tun hat.
Man kann sich von std::chrono inspirieren lassen:
https://en.cppreference.com/w/cpp/header/chrono
Dort gibt es Datentypen wie std::chrono::nanoseconds und user-defined
literale wie operator""ns . Durch die Kodierung der Einheit im Datentyp
vermeidet man Fehler und kann die Daten auch generisch verarbeiten.
Wie man es nicht macht kann man sich bei FreeType2 anschauen:
https://www.freetype.org/freetype2/docs/reference/ft2-basic_types.html#ft_pos
Es ist entweder "integer font units, or 16.16, or 26.6 fixed-point pixel
coordinates". Statt FT_Pos16_16, FT_Pos26_6 und FT_PosFontUnit o.ä. zu
definieren darf man raten was es jeweils ist.
Niklas G. schrieb:> Man kann sich von std::chrono inspirieren lassen:>> https://en.cppreference.com/w/cpp/header/chrono>> Dort gibt es Datentypen wie std::chrono::nanoseconds und user-defined> literale wie operator""ns . Durch die Kodierung der Einheit im Datentyp> vermeidet man Fehler und kann die Daten auch generisch verarbeiten.
std::chrono ist nicht gerade das beste Beispiel.
Es gibt:
1
std::chrono::nanoseconds
2
std::chrono::microseconds
3
std::chrono::milliseconds
4
std::chrono::seconds
5
std::chrono::minutes
6
std::chrono::hours
7
std::chrono::days
8
std::chrono::weeks
9
std::chrono::months
10
std::chrono::years
als Alias für bestimmte std::chrono::duration Typen und es gibt
1
operator""ns
2
operator""us
3
operator""ms
4
operator""s
5
operator""min
6
operator""h
7
operator""d
8
operator""y
als Literals. Wer genauer hinschaut, wird feststellen, dass kein Literal
für den Monat gibt. Und wer nachschaut, was diese Literale genau für
einen Typ erzeugen, wird feststellen, dass die ersten 6 die
entsprechenden std::chrono::duration Typen liefern. Die d und y Literale
liefern die Typen std::chrono::day und std::chrono::year Typen, die
nichts mit std::chrono::duration zu tun haben.
Interessant sind auch die Datentypen von t1 und t2.
1
autot1=12s/3;
2
autot2=12m/3;
Dann bleibt noch die Frage, welchen namespace man braucht, um die
Literals zu nutzen? std::literals, std::chrono,
std::literals::chrono_literals oder
std::chrono::literals::std_chrono_literals?
Und wer etwas anderes als den "proleptic Gregorian calendar" (oder Jahre
die außerhalb von ±2^15] liegen) benötigt, ist mit std::chrono eh
verloren.