Forum: Mikrocontroller und Digitale Elektronik int und long miteinander verrechnen und int Resultat?


von Käferlein (Gast)


Angehängte Dateien:

Lesenswert?

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.

von EAF (Gast)


Lesenswert?

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?

von Käferlein (Gast)


Lesenswert?

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.
;-)

von PittyJ (Gast)


Lesenswert?

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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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) -...

von wo ist der Unterschied (Gast)


Lesenswert?

int = long * 0.95 geht nicht.

warum soll int = long * 95 / 100 gehen?

Die Kommas werden in beiden Fällen abgeschnitten.

von Keks F. (keksliebhaber)


Lesenswert?

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.

von Axel R. (axlr)


Lesenswert?

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
von A. S. (Gast)


Lesenswert?

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.

von Käferlein (Gast)


Lesenswert?

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?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
von Zeno (Gast)


Lesenswert?

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.

von A. S. (Gast)


Lesenswert?

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);

von Rolf M. (rmagnus)


Lesenswert?

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.

von Käferlein (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.