Forum: Compiler & IDEs Variablentyp cast-Problem


von Sven (Gast)


Lesenswert?

Hallo,

ich habe ein Problem mit einer Rechnung.
Ich möchte eine Tabelle mit konstanten Faktoren am Anfang des Programms 
errechnen lassen.
ssTabelle wird anfangs mit Werten befüllt (hier 4 Stück als Beispiel), 
die das Programm dann später ausrechnen soll.
Die Array hierfür ist als int16_t definiert, da die Anfangsbefüllung und 
auch die Werte NACH erfolgter Rechnung in ein int16_t passen.
Jetzt kommt es aber bei der Rechnung selbst zu einem Überlauf von 
16-bit, da die Werte zunächst mit 4000 multipliziert werden (damit 
größer als 16-bit) und im Anschluss durch (n*3) geteilt werden. Wird 
durch n*3 geteilt, passen die Zahlen wieder 16-bit.
Allerdings funktioniert das Ganze leider nicht. Es kommt nicht die Zahl 
raus, die rauskommen soll (gebe sie mir auf dem Display aus).
1
#define AnzahlFaktoren   400
2
3
uint16_t n;
4
int16_t ssTabelle [AnzahlFaktoren] = {0,112,114,0};
5
for (n=10; n<AnzahlFaktoren; n++){
6
ssTabelle[n] = (int32_t)(4000*ssTabelle[n])/(n*3);
7
}

Hat jemand einen Lösungsvorschlag?
Wenn ich ssTabelle als int32_t wähle, funktioniert die Rechnung. Wollte 
aber nicht den Speicherplatz vergeuden.

Danke.

von master of cast (Gast)


Lesenswert?

Sven schrieb:
> ssTabelle[n] = (int32_t)(4000*ssTabelle[n])/(n*3);
1
ssTabelle[n] = (int16_t)((int32_t)(4000*ssTabelle[n])/(n*3));

von Sven (Gast)


Lesenswert?

master of cast schrieb:
> ssTabelle[n] = (int16_t)((int32_t)(4000*ssTabelle[n])/(n*3));

Sicher, dass dies so gehen wird? Irgendwie zeigt mein Display immernoch 
nicht auf mit diesen Zeilen das richtige Ergebnis

von Stefan E. (sternst)


Lesenswert?

1
ssTabelle[n] = (4000L*ssTabelle[n])/(n*3);
Oder wenn es unbedingt ein Cast sein soll:
1
ssTabelle[n] = ((int32_t)4000*ssTabelle[n])/(n*3);

von Sven (Gast)


Lesenswert?

Hallo Stefan,

das funktioniert jetzt.
Wenn du mir jetzt noch kurz erklären könntest, wieso das genau so 
gemacht werden muss, wäre ich dankbar.
Ich dachte c führt die Rechnung immer mit der höchsten Datentyp aus, 
hier durch meinen "gedachten" cast auf (int32_t) also mit 32-bit. Wieso 
muss ich noch das L für long dann an der 4000 anfügen?

Grüße
Sven

von loser of cast (Gast)


Lesenswert?

Stefan Ernst schrieb:
> ssTabelle[n] = ((int32_t)4000*ssTabelle[n])/(n*3);

natürlich, Depp ich.

Nicht das Ergebnis casten, sondern einen Operanden!

von Sven (Gast)


Lesenswert?

Ok, das ist wohl dann auch die Erklärung, das wenn man das (int32_t) an 
den Anfang stellt, das gesamte Ergebnis gecastet wird, aber die 
Operanden alle 16-bit sind und daher auch in 16-bit gerechnet wird...

von Stefan E. (sternst)


Lesenswert?

Sven schrieb:
> Ich dachte c führt die Rechnung immer mit der höchsten Datentyp aus,
> hier durch meinen "gedachten" cast auf (int32_t) also mit 32-bit.

Ja, aber ...
1
(int32_t)(4000*ssTabelle[n])
... wo ist denn hier innerhalb der Klammer ein int32_t?
Innerhalb der Klammer sind nur int und int16_t, also wird auch die 
Multiplikation in int gemacht. Erst das (bereits übergelaufene) Ergebnis 
wird dann von dir mit dem Cast in ein int32_t konvertiert.

von Sven (Gast)


Lesenswert?

Besten Dank für die aufklärungsreiche Antwort und schnelle Hilfe am 
späten Abend!

Gute Nacht!

von Nachtwächter (Gast)


Lesenswert?


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.