Ich hab da mal eine Rechenfrage:
In Zeile 53 muss ich den Wert pges als long definieren,
weil ich ihn zur Leistungsfaktorkorrektur 0,95 mit 95
multiplizieren und dann durch 100 dividieren muss.
Das passiert in den Zeilen 350 bis 357.
Letztendlich soll der ertrag als int ausgegeben werden.
Geht das einfach so wie ich das da mache, oder macht man das anders?
Es scheint zu funktionieren, bin mir aber unsicher.
Käferlein schrieb:> // Reset alle 24h.
Ich bin schockiert!
Wozu soll das sein....?
Dann scheinst du ein if Liebhaber sein.... (und der globalen Variablen)
Schon vom Range basiertem switch/case gehört?
Der Gcc kann das.
Zu deiner eigentlichen Frage, kann ich nicht viel sagen.
1. Die Variablen Definitionen sind zu weit weg vom Code, mein Scrollrad
ist mir zu schade dafür.
2. Zudem kenne ich die Realdaten nicht
Warum baust du keinen minimal Test, und kundschaftest so die Grenzen
aus?
EAF schrieb:> 1. Die Variablen Definitionen sind zu weit weg vom Code, mein Scrollrad> ist mir zu schade dafür.
strg+f Zeilenzahl in der Codeansicht.
;-)
Käferlein schrieb:> EAF schrieb:>>> Die Variablen Definitionen sind zu weit weg vom Code, mein Scrollrad>> ist mir zu schade dafür.>> strg+f Zeilenzahl in der Codeansicht.> ;-)
Mein Tablet hat kein strg.
Wenn du nur diese Berechnungsfragen hast, hätte ein Auszug aus dem Code
gereicht.
Käferlein schrieb:> Geht das einfach so
Mein Tipp: lies millis() nur ein einziges Mal am Anfang der
Hauptschleife ein und arbeite im ganzen Durchlauf mit dieser Zeit. Denn
sonst hast du im Verlauf der Schleife laufend eine andere Zeit und
kannst dir so ganz leicht einen schwer zu findenden sporadischen Fehler
basteln...
Und zur eigentlichen Frage:
Nimm einen cast, dann gibt's keine Unklarheit.
ertrag = (int)(((pges * 95) / 100) -...
Kannst du machen, wie du es vorgeschlagen hast.
Der Code ist allgemein sehr unübersichtlich und hat wie erwähnt einige
Flüchtigkeitsfehler.
Du kannst auch zu long casten.
Du kannst auch zuerst dividieren, dann multiplizieren, mit dem
entsprechenden Genauigkeitsverlust.
Das sind deine drei Optionen. Was du davon nehmen kannst und willst,
musst du entscheiden.
Mal 243 rechnen und dann durch 256 teilen geht nicht? Skalieren ist
schon richtig, damit die kommastellen nicht verloren gehen. Da wird ja
nix gerundet, sondern einfach abgeschnitten.
Oder 973 und dann durch 1024 teilen?
Ansonsten kann man das schon so rechnen.
Käferlein schrieb:> In Zeile 53 muss ich den Wert pges als long definieren,> weil ich ihn zur Leistungsfaktorkorrektur 0,95 mit 95> multiplizieren und dann durch 100 dividieren muss.
Nein. Wenn int vor der Multiplikationen ausreicht, kannst Du auch nur
die Rechnung in Long machen, z.b. indem Du 95L statt 95 schreibst
Bei 95/100 geht auch: pges-=pges/20.
Lothar M. schrieb:> Und zur eigentlichen Frage:> Nimm einen cast, dann gibt's keine Unklarheit.>> ertrag = (int)(((pges * 95) / 100) -...
Danke. :)
A. S. schrieb:> Bei 95/100 geht auch: pges-=pges/20.
Wow Du bist ja ein Mathegenie. Die Lösung gefällt mir,
weil alles int sein kann.
1
pges = pa + pb + pc; // Gesamtscheinleistung der Solarpanele
Käferlein schrieb:> Ist es sicherer den Term pges / 20 extra zu klammern?
Kennst du "Punkt vor Strich"? (*)
Sieh dir unbedingt die "Priorität von Operatoren" an. Dann nutzen sich
deine Klammer-Tasten nicht so schnell ab. Und der Code ist leserlicher.
Auch ein Gleichheitszeichen ist ein Operator (mit ziemlich niedriger
Priorität. Trotzdem könntest du in jeder Berechnung ein Klammerpärchen
sparen.
Du musst nicht schreiben c = (a + b); sondern c = a + b; reicht aus,
weil + eine höhere Priorität hat als =
(*) wobei blöderweise ein : in C als Strich geschrieben wird... :-/
EAF schrieb:> Ich bin schockiert!> Wozu soll das sein....?>> Dann scheinst du ein if Liebhaber sein.... (und der globalen Variablen)> Schon vom Range basiertem switch/case gehört?> Der Gcc kann das.>> Zu deiner eigentlichen Frage, kann ich nicht viel sagen.> 1. Die Variablen Definitionen sind zu weit weg vom Code, mein Scrollrad> ist mir zu schade dafür.> 2. Zudem kenne ich die Realdaten nicht
Wieder mal typisch µC-Net. Da stellt einer eine Frage und an statt diese
zu beantworten, was ja mit einem einfachen Satz möglich wäre (Keks.F
hat's vorgemacht), wird erst mal auf dem TO herum gehackt, um ihm dann
noch zu sagen das man eigentlich keine Lust dazu hat ihm zu helfen.
Offenbar war das Scrollrad nicht zu schade, um den Code sich mal
anzusehen.
Sicher kann man den Code besser und optimaler gestalten, das kann man
aber auch anders sagen. Ich vermute mal das der TO das nicht jeden Tag
macht und ihm deshalb die Übung fehlt. Dazu ist das Ganze auch recht
ordentlich kommentiert, so das man als Außenstehender durchaus erkennen
kann was der TO vor hat, auch wenn man die "Realdaten" nicht kennt,
wobei deren Kenntnis für die Beantwortung der Frage auch völlig
irrelevant ist.
@TO
Deine Frage wurde ja schon ausrereichend beantwortet.
Allerdings kann man das eine oder andere auch etwas umschreiben, denn
die vielen if's sind wirklich nicht notwendig und erschweren das Lesen,
auch wenn es von der Funktion her korrekt ist.
Bei so etwas wie
Tiefe Verschachtelungen mit if/else kann man recht einfach mit dem
switch/case Konstrukt entschärfen und überscichtlicher gestalten.
Am Ende ist das aber alles Kosmetik und für die Funktion des Codes
unerheblich. Ziehe es erst mal so durch wie Du es angefangen hast. Wenn
es dann wie gewünsch funktioniert, kannst Du ja immer noch eine neue
Version 2.0 mit optimierten Code auflegen.
Jeder hat mal klein angefangen, leider vergessen das die meisten hier.
Käferlein schrieb:>> ertrag = (int)(((pges * 95) / 100) -...>> Danke. :)
Aber nicht vergessen, pges auch zu int zu machen und das long nur
temporär in die Rechnung, z.B.:
1
intpges;
2
3
...
4
ertrag=((int)((pges*95L)/100))-...
Meist sind Speicher und Geschwindigkeit egal, wenn man den größeren
Datentyp nimmt. Doch wenn man kleinere Typen braucht, sollte man auch in
denen bleiben, kleineren bleiben, damit der Compiler notfalls warnen
kann.
Wenn pges in ein int passt, dann auch 95% davon. Wenn pges long ist und
Du nachher einen längeren Term auf int castest, wirft der Compiler auch
dann keine Warnung mehr, wenn das Ergebnis ganz sicher nicht reinpasst.
Ein Cast sagt dem Compiler: Egal wie offensichtlich falsch das ist, ich
weiss, was ich tue. Deshalb sind casts genauso evil wie notwendig.
Beispiel mit int = 16 Bit:
wo ist der Unterschied schrieb:> int = long * 0.95 geht nicht.
Sicher geht das, aber es führt dazu, dass die Berechnung in double
durchgeführt wird.
> warum soll int = long * 95 / 100 gehen?
Warum sollte es nicht gehen?
> Die Kommas werden in beiden Fällen abgeschnitten.A. S. schrieb:> Nein. Wenn int vor der Multiplikationen ausreicht, kannst Du auch nur> die Rechnung in Long machen, z.b. indem Du 95L statt 95 schreibst>> Bei 95/100 geht auch: pges-=pges/20.
Das rundet allerdings immer auf (für positive Werte), während die andere
Variante immer abrundet.