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) -...
int = long * 0.95 geht nicht. warum soll int = long * 95 / 100 gehen? Die Kommas werden in beiden Fällen abgeschnitten.
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.
:
Bearbeitet durch User
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 |
2 | |
3 | if(inselbetrieb == LOW){ |
4 | ertrag = ((pges - pges / 20) - (pd + synchronleistung)); // Leistungsfaktor Wechselrichter 0,95 |
5 | } |
6 | else { |
7 | ertrag = ((pges - pges / 10) - (pi + synchronleistung + 20 )); // Leistungsfaktor Wechselrichter 0,90 |
8 | } |
Bitte mal prüfen. Ist es sicherer den Term pges / 20 extra zu klammern?
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... :-/
:
Bearbeitet durch Moderator
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
1 | if((relx != relxvorher) || (rely != relyvorher) || (relz != relzvorher)) { |
2 | 212
|
3 | umschalten = HIGH; |
4 | } else { |
5 | umschalten = LOW; |
6 | }
|
kann man einfach schreiben
1 | umschalten = ((relx != relxvorher) || (rely != relyvorher) || (relz != relzvorher)) |
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 | int pges; |
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:
1 | int a = 1000; |
2 | long b = 1000; |
3 | |
4 | int e_a, e_b; |
5 | |
6 | e_a = a*100; |
7 | e_b = (int) (b*100); |
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.
Käferlein schrieb: > Bitte mal prüfen. Funktioniert ganz wunderbar. :) Zeno schrieb: > kann man einfach schreibenumschalten = ((relx != relxvorher) || (rely != > relyvorher) || (relz != relzvorher)) Danke, mache ich beim nächsten Update.
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.