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?
:
Bearbeitet durch User
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):
1 | const Millis interval {25_ms}; |
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.
Hier mal wie das aussehen könnte:
1 | using Frequency = uint64_t; |
2 | |
3 | Frequency operator "" _Hz(unsigned long long int val) |
4 | { |
5 | return val; |
6 | } |
7 | |
8 | Frequency operator "" _kHz(unsigned long long int val) |
9 | { |
10 | return val * 1000; |
11 | } |
12 | |
13 | Frequency freq1 = 1_Hz; |
14 | Frequency freq2 = 23_kHz; |
Dokumentiert sich quasi selber der Code.
Zehpluplus schrieb: > Hier mal wie das aussehen könnte: > >
1 | > using Frequency = uint64_t; |
2 | > |
3 | > Frequency operator "" _Hz(unsigned long long int val) |
4 | > { |
5 | > return val; |
6 | > } |
7 | > |
8 | > Frequency operator "" _kHz(unsigned long long int val) |
9 | > { |
10 | > return val * 1000; |
11 | > } |
12 | > |
13 | > Frequency freq1 = 1_Hz; |
14 | > Frequency freq2 = 23_kHz; |
15 | > |
> > Dokumentiert sich quasi selber der Code. So macht man das sicher nicht: ein einfacher alias reicht nicht. schlechte Fortsetzung:
1 | using Bla = uint64_t; |
2 | Frequency freq1 = 1_Hz; |
3 | Frequency freq2 = 23_kHz; |
4 | |
5 | Bla b = 23_kHz; // Ups |
6 | |
7 | auto x = b * freq1; // What? |
8 | }
|
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 ...
Wilhelm M. schrieb: > So macht man das sicher nicht: ein einfacher alias reicht nicht. Hier ist ein besseres Bespiel: https://www.geeksforgeeks.org/user-defined-data-types-in-c/
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
:
Bearbeitet durch User
@ 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.
:
Bearbeitet durch User
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 | auto t1 = 12s / 3; |
2 | auto t2 = 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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.