Hi,
ich habe in meinem Code immer mal Konstrukte, welche aus Gründen der
Les- und Nachvollziehbarkeit länger sein können, als sie eigentlich
müssten. Ein Beispiel:
corrX=(((65535.0F/size)*realX)+32767)*1024.0F;
Diese Formel könnte man so vereinfachen, dass die abschließende
Multiplikation wegfällt. Allerdings will ich im Code gerne sehen, dass
das Ganze an dieser Stelle um den Faktor 1024 vergrößert wurde, weswegen
ich diese Schreibweise bevorzuge.
Meine Frage: kann der Compiler das optimieren, sprich vereinfacht er mir
diese Formel? Oder bleibt tatsächlich die umständlichere Variante im
Code?
Danke!
Was auch immer "Der Compiler" ist, du kannst zumindest davon ausgehen,
das konstante Ausdrücke schon bei der Compilierung berechnet werden. Es
gibt auch noch weitergehende Optimierungen, aber da wirst du schon
nachschauen müssen, was für Code für deine Zielplattform erzeugt wird.
Oliver
@ Plankton (Gast)
>corrX=(((65535.0F/size)*realX)+32767)*1024.0F;>Diese Formel könnte man so vereinfachen, dass die abschließende>Multiplikation wegfällt. Allerdings will ich im Code gerne sehen, dass>das Ganze an dieser Stelle um den Faktor 1024 vergrößert wurde, weswegen>ich diese Schreibweise bevorzuge.
Was bei der Rechung mit Fließkommazahlen totaler Unsinn ist. Solche
Tricks braucht man nur bei Festkommaarithmetik.
>Meine Frage: kann der Compiler das optimieren, sprich vereinfacht er mir>diese Formel?
Nein, denn dann wäre das Ergebnis anders, weil zwischendurch Rundungen
und Überläufe auftreten können. Wie die Formelinterpratation und ggf.
Vereinfachung im Detail abläuft, sagt dir der C-Standard oder die
C-Profi hier.
>Oder bleibt tatsächlich die umständlichere Variante im>Code?
Ich meine, Ja.
Falk B. schrieb:>>corrX=(((65535.0F/size)*realX)+32767)*1024.0F;>>>Diese Formel könnte man so vereinfachen, dass die abschließende>>Multiplikation wegfällt. Allerdings will ich im Code gerne sehen, dass>>das Ganze an dieser Stelle um den Faktor 1024 vergrößert wurde, weswegen>>ich diese Schreibweise bevorzuge.>> Was bei der Rechung mit Fließkommazahlen totaler Unsinn ist. Solche> Tricks braucht man nur bei Festkommaarithmetik.
Verstehe ich nicht, wieso ist das Unsinn?
Plankton schrieb:> Verstehe ich nicht, wieso ist das Unsinn?
Die Multiplikation einer binären Fliesskommazahl mit 1024 entspricht
ungefähr der Multiplikation einer dezimalen Fliesskommazahl mit
10000000000 aka 1.0e10. Soll heissen: Die Mantisse wird mit 1
multipliziert und es wird 10 zum Exponenten hinzu addiert.
Das kann man zwar machen - aber weshalb?
A. K. schrieb:> Das kann man zwar machen - aber weshalb?
Ähm, weil ich später halt einen Wert benötige, der um den Faktor 1024
größer ist? Alternativ kann ich bei den folgenden, viel häufiger
auftretenden Rechenoperationen auch jedes mal mit 1024 multiplizieren,
was aber definitiv umständlicher ist, als das einmal an zentraler Stelle
zu machen.
Plankton schrieb:> was aber definitiv umständlicher ist, als das einmal an zentraler Stelle> zu machen.
Wenn die Berechnung nur sehr selten ausgeführt wird ist es meistens
unnötig sich Gedanken über eine Optimierung bezüglich der
Geschwindigkeit zu machen, da ist es sinnvoller eine ausreichende
Rechengenauigkeit zu erhalten.
Du möchtest, dass der Compiler das Distributivgesetz anwendet und aus
1
corrX=(((65535.0F/size)*realX)+32767)*1024.0F;
dieses
1
corrX=67107840.0/size*realX+33553408.0;
macht?
Nein, das tut er nicht, da dadurch ein Überlauf enstehen könnte, der in
der ursprünglichen Schreibweise nicht auftritt. Das wird in deinem
konkreten Fall zwar wahrscheinlich nicht passieren, aber der Compiler
kennt die Wertebereiche von size und realX nicht, weswegen er auf Nummer
Sicher geht und die Umformung bleiben lässt.
Anders sieht es bei Integer-Berechnungen aus, wo garantiert werden kann,
dass das Ergebnis nach der Umformung für alle Variablenwerte dasselbe
bleibt. Zumindest der GCC würde dann die gewünschte Umformung vornehmen.
Man kann das Ganz in C++ durch user-defined-literals wesentlich lesbarer
machen. Dazu kann man durch die entsprechenden Operatoren für UDTs auch
sicherstellen, dass bei der Division von Länge und Zeit z.B. auch eine
Geschwindigkeit heraus kommt.
Gepaar wird das ganz mit constexpr, so dass man sicher ist, dass diese
Berechnungen auch zur Compile-Zeit ausgeführt werden.
So berechne ich bspw. die Timer-Parameter für vorgegebene
Timer-Interrupt-Frequenzen.
Und constexpr-Ausdrücke können dann auch wieder als template-parameter
dienen ...
Constexpr führt bei solchen Ausdrücken zu keiner gründlicheren
Compilezeitberechnung als const oder auch gar kein qualifier. Der
Compiler berechnet da sowieso so viel selber, wie er kann.
Oliver
Es geht ja nicht um gründlicher ...
Es geht darum, dass eine Berechnung, in der eine / mehrere Funktionen
auftauchen, dann auch tatsächlich zur Compilezeit ausgeführt wird. Das
hat mit const nichts zu tun.
> =(((65535.0F/size)*realX)+32767)*1024.0F;
Für mich sieht das auch irgendwie schräg aus. also in hex:
(((double)(0xffff))/size)*realX)+0x7fff)*((double) 0x400));
bzw.
(((double)(0x10000-1))/size)*realX)+0x8000-1)*((double) 0x400));
Für mich sieht das so aus, als würdest Du mit den "MägicNambas"
bestimmte "Dinge" erreichen wollen, irgendwas mit Fixpoints, wie Falk ja
schon schrieb.
Wenn Du Dir entsprechende Inliner oder Makrso machst, ist es sicher
klarer und ggf. vom Compiler auflösbar. Je nach dem was Du da machen
willst z.B.:
jetzt ist die Multiplikation mit 1024 zwar per Hand doppelt, aber nur
einmal und im Code steht (wenn Du uns sagst, was das soll) ein
aussagekräftiger Begriff. Der Compiler arbeitet optimal, der Leser
braucht keine Magic-Numbers (mit Zaunlatten-Problemen) zu merken.
Wilhelm M. schrieb:> Gepaar wird das ganz mit constexpr, so dass man sicher ist, dass diese> Berechnungen auch zur Compile-Zeit ausgeführt werden.
Achtung, constexpr alleine ist keine Garantie für eine Berechnung zur
Compile Zeit. Dies wird dir auch keine Warnings erzeugen, sollte es erst
zur Laufzeit berechnet werden.
Operator S. schrieb:> Wilhelm M. schrieb:>> Gepaar wird das ganz mit constexpr, so dass man sicher ist, dass diese>> Berechnungen auch zur Compile-Zeit ausgeführt werden.>> Achtung, constexpr alleine ist keine Garantie für eine Berechnung zur> Compile Zeit. Dies wird dir auch keine Warnings erzeugen, sollte es erst> zur Laufzeit berechnet werden.
Du hast Recht für constexpr Funktionen.
Wenn man aber constexpr Objekte / Variablen hat, dann schon! Werden die
mit einem Funktionswert initialisiert, der nicht constexpr sein kann, so
bekommt man einen Fehler.
Achim S. schrieb:> Plankton schrieb:>> Nein, das sind keine "Magic Numbers".>> Aha? Wir kennen Deinen Code oder Deine Aufgabe ja nicht.
Ja...und? Genügt dir diese Aussage nicht? Was soll ich machen, dass du
es glaubst - soll ich die Information für dich singen?
Plankton schrieb:> Ja...und? Genügt dir diese Aussage nicht? Was soll ich machen, dass du> es glaubst - soll ich die Information für dich singen?
Mal ganz langsam, du willst hier Hilfe!
Und die erste Regel in dem (und allen anderen) Forum(en) ist:
Hinterfrage grundsätzlich alle Aussagen des TOs.
Beispiele gerade aktuell hier im Forum:
Ein Rasenmähermotor 12V 500W der aber angeblich nur 4,5A unter Last
zieht.
Oder ein Kupferwürfel mit den Abmessungen:
"Grundfläche des Würfels ist ungefähr 35mm+35mm und die Höhe beträgt
70mm."
Plankton schrieb:> Ja...und? Genügt dir diese Aussage nicht? Was soll ich machen, dass du> es glaubst - soll ich die Information für dich singen?
ich multipliziere mit 3.14159265... hat aber nichts mit Pi zu tun. Wenn
(2^10), (2^15-1) und (2^16-1) sich bei Dir zufällig ergeben, dann ist
das halt Zufall.
Da brauchst Du uns nichts vorzusingen.
Plankton schrieb:> Nein, das sind keine "Magic Numbers".
Selbstverständlich sind es magic numbers. Wenn man diese Zeile liest:
corrX=(((65535.0F/size)*realX)+32767)*1024.0F;
dann weiß man nicht, warum da gerade z.B. 32767 steht. Und nicht etwa
32768. Oder 8192. Oder sonst irgendwas.
Das ist genau die Definition einer "magic number": Der Sinn und Zweck
einer Zahl bleibt im Verborgenen. Und dort gehört er nicht hin.
Weil das Wort Kommentare bis hier nur nur einmal auftaucht:
c.m. schrieb:> zur nachvollziehbarkeit gibts kommentare im code.
Da können dann auch die Magic Numbers erklärt werden.
Richtig benannte Konstanten sind aber besser.
Kommentare sind auch oft zweifelhaft: denn der Kommentar altert anders
als der Code.
Ich habs oben ja schon mal geschrieben: eigene Datentypen mit den
entsprechenden Operatoren und user-defined-literals (obgleich ich
vermute, dass es reiner C Code ist - allerdings könnte man auch nur
wegen dieses Aspekts einen C++ Compiler benutzen).
Der Andere schrieb:> Plankton schrieb:>> Ja...und? Genügt dir diese Aussage nicht? Was soll ich machen, dass du>> es glaubst - soll ich die Information für dich singen?>> Mal ganz langsam, du willst hier Hilfe!
Richtig. Aber muss ich deswegen rechtsgültige Beweise vorlegen, wenn ich
eine Rückfrage beantworte? Wenn jemandem die Antwort, die er bekommt,
nicht passt, dann kann ich da auch nichts dafür.
Und nein, es sind trotzdem keine Magic Numbers, der Sinn ergibts sich
aus der Genauigkeit der Eingangdsaten (es gibt mehrere Detenquellen
unterschiedlicher Genauigkeit) und hat absolut NICHTS mit der
eigentlichen Frage zu tun, die schon lange beantwortet wurde.
Plankton schrieb:> Und nein, es sind trotzdem keine Magic Numbers
Doch. Sieh es einfach ein.
> der Sinn ergibts sich aus der Genauigkeit der Eingangdsaten (es gibt> mehrere Detenquellen unterschiedlicher Genauigkeit)
Dann benennt man diese Konstanten eben so, dass man sinnvolle Namen hat
aus denen man ersehen kann wofür sie gut sind.
> und hat absolut NICHTS mit der eigentlichen Frage zu tun, die schon lange> beantwortet wurde.
Damit wirst Du leben müssen. Du kannst den Leuten nicht vorschreiben,
welche Antworten sie Dir zu geben haben.
Mark B. schrieb:>> und hat absolut NICHTS mit der eigentlichen Frage zu tun, die schon lange>> beantwortet wurde.>> Damit wirst Du leben müssen. Du kannst den Leuten nicht vorschreiben,> welche Antworten sie Dir zu geben haben.
Und die Leute werden damit leben müssen, dass sie eine entsprechende
Reaktion erhalten, wenn sie Fragen beantworten, die nicht gestellt
werden.
Das ist in diesem Forum hier übrigens eine extreme Unsitte, anderswo ist
die Neigung, unbedingt irgendwelchen (nutzlosen) Senf dazuzugeben,
deutlich geringer.
Plankton schrieb:> Das ist in diesem Forum hier übrigens eine extreme Unsitte, anderswo ist> die Neigung, unbedingt irgendwelchen (nutzlosen) Senf dazuzugeben,> deutlich geringer.
Ist klar: Der Fehler liegt immer bei den anderen, nie bei einem selbst.
;-)
Benannte Konstanten sind eben nicht nutzlos, sondern sie tragen zu
besserem Code bei.