mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Datentypen in Operationen


Autor: André Wippich (sefiroth)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen!

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

double r = i / j;

// 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#Datent...

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:
double r = (5 / 2) + (7 / (3 / 2) );

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

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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) );

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom schrieb:
> So wird nur float gerechnet und dann dem double zugewiesen.

Das weißt du sicher?

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nach C-Standard finden alle (Gleitklomma-)Berechnungen eh in
double statt (außer bei long double natürlich), und 1.0 ist
eine double-Konstante.


Beim avr-gcc kommt dazu, daß float ebenso wie double 4 Byte
haben und einfach gleich sind.

Autor: André Wippich (sefiroth)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber Tom hat schon recht, ich wollte das gerne mit Typecasts machen. Die 
Zahlen habe ich nur als Vereinfachung verwendet, um nicht noch einen 
Haufen Variablen mit einführen zu müssen. Absicht der Frage war quasi 
wie viele Typecasts wirklich nötig sind.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: André Wippich (sefiroth)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank! Genau das wollte ich wissen :-)

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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."

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Genau das hatte ich eben doch auch geschrieben.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.