Datentypen in Operationen

OP #1984357
Lesenswert?

Hallo zusammen!

Ein häufiges Problem bei Rechnungen ist ja der vergessene Datentyp von 
Operanden bei Rechnungen, wie in dem Beispiel:
1
int i = 5;
2
int j = 2;
3

4
double r = i / j;
5

6
// Ergebnis in r ist 2 und nicht 2.5 wie vielleicht erwartet, da beide Operanden vom Typ int sind und daher auch das Ergebnis der Division vom Typ int.

Das wird hier auch sehr gut beschrieben und sollte soweit auch allgemein 
bekannt sein:
http://www.mikrocontroller.net/articles/FAQ#Datentypen_in_Operationen

Was ich gerne fragen wollte ist, wie es sich mit komplexeren Rechnungen 
verhält. Genügt es wenn irgendein Operand einen Typecast bekommt, damit 
die gesamte Rechnung in diesem Type durchgeführt wird? Oder muss es (wie 
ich bisher angenommen habe) immer der zuerst vom Compiler angefasste 
Operand sein?

Mal folgende Beispielrechnung angenommen:
1
double r = (5 / 2) + (7 / (3 / 2) );

Wie würdet Ihr sie typecasten, damit sie sauber berechnet wird? Mein 
Vorschlag wäre:
1
double r = ( (double) 5 / 2) + (7 / ( (double) 3 / 2) );
#1984362
Lesenswert?

Es reicht, wenn einer z.B. double ist, damit die Rechnung in double 
stattfindet - egal welcher der beiden.

Es ist also egal, ob r=1.0/2 oder r=1/2.0 oder r=1.0/2.0 gerechnet wird.

André Wippich schrieb:
> Wie würdet Ihr sie typecasten, damit sie sauber berechnet wird? Mein
> Vorschlag wäre:double r = ( (double) 5 / 2) + (7 / ( (double) 3 / 2) );

Meiner: r = ( 5.0 / 2.0) + (7.0 / (3.0 / 2.0) );
Gast #1984377
Lesenswert?

> double r = ( (double) 5 / 2) + (7 / ( (double) 3 / 2) );

So ist es richtig. Alles wird double gerechnet.

> r = ( 5.0 / 2.0) + (7.0 / (3.0 / 2.0) );

So wird nur float gerechnet und dann dem double zugewiesen. Und der TO 
wollte das mit typecasts machen.
#1984439
Lesenswert?

André Wippich schrieb:

> Was ich gerne fragen wollte ist, wie es sich mit komplexeren Rechnungen
> verhält.

Ich denke deine eigentliche Frage ist noch nicht wirklich beantwortet.

Auch ein komplexere Berechnung ist letztenendes ja nur eine Abfolge von 
einfachen Operationen. Nur ist halt das Ergebnis einer Operation 
wiederrum Operand für die nächste Operation.

Und in allen Stufen wird erneut entschieden: linker Operand, rechter 
Operand, wie wird die Operation implementiert.


d.h. die Berechnung

  int a = 5, b = 8;
  double c;

  c = 8.0 + b * a;

laut den Rechenregeln, wird so gerechnet

    b * a   ->   Zwischenergebnis
                         |
                         |
                         +--->  + 8.0

b ist ein int, a ist ein int. Also erfolgt da eine int Multiplikation. 
Das Ergebnis davon ist wieder int.

Also ist Zwischenergebnis vom Datentyp int.

Um dieses mit 8.0 (einem double) zu addieren, wird dieses 
Zwischenergebnis zu einem double umgeformt und die Addition 
durchgeführt. Das Ergebnis hat dann ebenfalls Datentyp double und muss 
nicht weiter behandelt werden um an c zugewiesen zu werden.

Also immer einfach nur den Rechenregeln folgen: In welcher Reihenfolge 
wird ausgewertet, welche Datentypen sind beteiligt, welche Datentypen 
entstehen für die Zwischenergebnisse, was passiert mit den ZwischenErg. 
weiter?

So kannst du jeden Ausdruck analysieren.
#1984457
Lesenswert?

Klaus Wachtler schrieb:

> Nach C-Standard finden alle (Gleitklomma-)Berechnungen eh in
> double statt

Das war zwar anno K&R so, aber bereits in ANSI-C wurde das gestrichen 
und float+float darf als float gerechnet werden (die Konstanten bleiben 
natürlich double, sofern nicht explizit spezifiziert).

"First, if either operand has type long double, the other operand is 
converted to long double.  Otherwise, if either operand has type double, 
the other operand is converted to double.  Otherwise, if either operand 
has type float, the other operand is converted to float."
#1984466
Lesenswert?

A. K. schrieb:
> Klaus Wachtler schrieb:
>
>> Nach C-Standard finden alle (Gleitklomma-)Berechnungen eh in
>> double statt
>
> Das war zwar anno K&R so, aber bereits in ANSI-C wurde das gestrichen
> und float+float darf als float gerechnet werden (die Konstanten bleiben
> natürlich double, sofern nicht explizit spezifiziert).

das mag schon sein, nichts desto trotz ist 5.0 ein double

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren