www.mikrocontroller.net

Forum: Compiler & IDEs Warum habe ich hier einen Rechungsfehler?


Autor: Arni Blackcorner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute

Ich programiere mit WinAVR und bekommte ein falsches Resultat. Dieses 
Problem hatte ich auch schon. Zwar habe ich die Lösung dokumentiert, 
kann sie leider im Moment nicht finden. Muss irgendwass mit den 
unterschiedlichen Datentypen zu tun haben die man irgendwie in Klammern 
angeben muss. Leider weiss ich nicht mehr wie und weiss auch nicht unter 
welchem Thema man dies nachlesen kann.

Wer kann mir weiterhelfen?



unsigned int intTmp;
WORD intADW1;

intADW1 = ADReadPort(1);
intTmp = 100000 / 1024;
intTmp = intTmp * intADW1;
intTmp = intTmp / 1000;


Gruss

Arni Blackcorner

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
<< intTmp = 100000 / 1024;

(2^16 = 65.536 < 100.000)

Versuchs mal mit long int.

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich programiere mit WinAVR und bekommte ein falsches Resultat.
IST? SOLL?

Setz mal den größt möglichen Wert für ADReadPort(1); ein und rechne das 
von Hand durch. Ich wette, da treten Überläufe und Rundungsfehler auf.

Was genau soll der Code eigentlich machen?
intTmp = ADReadPort(1) * 25 / 256;

Macht dasselbe nur ohne Rundungsfehler und weniger Überläufe.
intTmp = ADReadPort(1) / 10;

Ist je nach gewünschter Genauigkeit auch noch recht dicht dran

Autor: Arni Blackcorner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Gast

Vermutlich hast du mich falsch verstanden. Ich will nicht beide 
Variablen gleich deklarieren.

Man kann irgendwie vor oder inter der Variable den Datentyp angeben 
damit es dann richtig rauskommt. Soviel ich weiss deklariert der 
Compiler im Voraus das Erebnis als Word wenn ich nicht angebe mit 
welchem Datentyp ich arbeite.

So ähnlich wie hier unten nur so geht es nicht.

intTmp = intTmp * intADW0 (int);

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

Bewertung
0 lesenswert
nicht lesenswert
Arni Blackcorner wrote:

> Man kann irgendwie vor oder inter der Variable den Datentyp angeben
> damit es dann richtig rauskommt. Soviel ich weiss deklariert der
> Compiler im Voraus das Erebnis als Word wenn ich nicht angebe mit
> welchem Datentyp ich arbeite.

So ungefähr. Aber der Datentyp ist int.

> So ähnlich wie hier unten nur so geht es nicht.
>
> intTmp = intTmp * intADW0 (int);

Wie wäre es mit etwas Literatur. Ohne wirst du bei einer Sprache
wie C ganz schnell auf die Schnauze fallen.

Was du suchst ist ein Cast:

 intTmp = intTmp * (int)intADW0;

und ob der dein Problem löst steht auf einem ganz anderen Blatt.
Generell: Je mehr du casten musst, desto schlechter.
Ein guter Code kommt mit wenigen casts aus. Manchmal geht es
nicht ohne, trotzdem muss man Casts mit Weisheit einsetzen und
keinesfalls als Waffe für alles.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Arni Blackcorner wrote:
> Man kann irgendwie vor oder inter der Variable den Datentyp angeben
> damit es dann richtig rauskommt.
So was nennt sich Typkonversion...

> Soviel ich weiss deklariert der
> Compiler im Voraus das Erebnis als Word wenn ich nicht angebe mit
> welchem Datentyp ich arbeite.
Der Compiler deklariert überhaupt nichts. Er rechnet nur (sofern nichts 
anderes angegeben ist) in int solange die Typen aller Operanden 
hineinpassen. Wenn nicht, dann wird der größte Datentyp, der vorkommt, 
als Grundlage genommen. Eine Zuweisung findet aber erst nach der 
Auswertung des Ausdruckes rechts vom "=" statt, so dass es bei der 
Berechnung überhaupt keine Rolle spielt, was links für ein Datentyp 
vorliegt. Und WORD solltest Du Dir besser schenken. Das bringt nur 
durcheinander. int ist nämlich generell vorzeichenbehaftet. Benutze am 
Besten die Datentypen aus der stdint.h. Die haben eine eingebaute 
Längenangabe.

> So ähnlich wie hier unten nur so geht es nicht.
>
> intTmp = intTmp * intADW0 (int);
Was soll das (int) hinter dem Operanden? Abgesehen davon, dass es 
nichts bringen dürfte, muss es davor und um Überläufe generell zu 
vermeiden, muss der Typ der Variable links vom "=" auch groß genug 
sein. Also eher
uint32_t intTmp;

intTmp = intADW0 * intTmp;
//oder
intTmp *= intADW0;
In diesem Fall kann man sich den cast (Typkonversion) sparen, weil 
intTmp ja bereits groß genug ist.

Ansonsten wäre es (allgemein)
uint16_t a, b;
uint32_t c;

c = (uint32_t)a * b;

Autor: Arni Blackcorner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe einige Bücher C++ (ich weiss ist nicht C) und habe etliche 
C-Bücher gestern in der Buchhandlung angesehen, nur genau so ein 
Probleme konnte ich keines finden. Da kann ich viel Geld ausgeben aber 
das Problem ist dann immer noch nicht gelöst.

Wenn mir aber Jemand so ein Buch empfehlen kann, welches solche Probleme 
behandelt dann wäre ich froh.

Dass der Datentyp "int"  war mir schon ganz am Anfang klar.

Also der Compiler frist die Sache mal. Im Moment noch noch nichts 
schlaues raus. Wird vermutlich was anderem liegen.

Muss man auch umgekhrt casten? Also wenn ich einen grossen Datentyp mit 
kleinem Wert einem kleinen Datentyp zuweise?


Sollte man am besten gleich die zu verrechnenen Datentypen genug gross 
wählen um nicht casten zu müssen?

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Arni Blackcorner wrote:
> Ich habe einige Bücher C++ (ich weiss ist nicht C) und habe etliche
> C-Bücher gestern in der Buchhandlung angesehen, nur genau so ein
> Probleme konnte ich keines finden.
Zum Thema Typkonversion sollte jedes C-Grundlagenbuch etwas sagen.

> Wenn mir aber Jemand so ein Buch empfehlen kann, welches solche Probleme
> behandelt dann wäre ich froh.
Kernighan/Ritchie: Programmieren in C...

> Dass der Datentyp "int"  war mir schon ganz am Anfang klar.
Ach ja? Warum schreibst Du dann "WORD"? Das ist was ganz anderes.

> Muss man auch umgekhrt casten? Also wenn ich einen grossen Datentyp mit
> kleinem Wert einem kleinen Datentyp zuweise?
Was soll das bringen?

> Sollte man am besten gleich die zu verrechnenen Datentypen genug gross
> wählen um nicht casten zu müssen?
Wenn Du viel Speicherplatz (und evtl. auch Rechenzeit, schließlich ist 
nicht gesagt, dass alle Operationen mit einer Variable den größeren 
Datentyp brauchen) unnötig verschwenden willst, dann kannst Du das tun.

Autor: Arni Blackcorner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke mal für die Hilfe. Ich werde nun versuchen die Sache umzusetzten.

Gruss

Arni Blackcorner

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Off topic...

Deutschlandradio http://www.dradio.de hat im Moment eine 10 Teilige 
Reihe mit dem Thema Verrechnet - Interessante Beispiele  wo die 
Mathematik zugeschlagen hat.

Kommt immer Dienstags aber man kann die ältere Sendungen (bisher 2) als 
MP3 aus dem Archiv herunterladen.

Diese Woche war ein Rundungsfehler in einer Patriot-Abwehrrakete dran, 
der sich bei langer Laufzeit des Steuerungscomputers fatal aufsummiert 
hat.

Autor: Arni Blackcorner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Diese Woche war ein Rundungsfehler in einer Patriot-Abwehrrakete dran,
>der sich bei langer Laufzeit des Steuerungscomputers fatal aufsummiert
>hat.

Klingt interessant. Da ist ja mein Rechnungsfehler noch harmlos.

Autor: neuer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
.....Diese Woche war ein Rundungsfehler in einer Patriot-Abwehrrakete 
dran,
der sich bei langer Laufzeit des Steuerungscomputers fatal aufsummiert
hat.......

ihr glaubt auch allen scheiss. wie leicht doch die menschen 
beeinflussbar sind. nur so kann man durch billige reklame euch allen 
mist vekaufen.

ihr sollte mal das richtige herausfiltern.

Autor: Arni Blackcorner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>ihr sollte mal das richtige herausfiltern.

Ja klar und vermutlich haben die Amis ja noch mit Absicht falsch 
gerechnet damit sie wieder einen Grund für einen Gegenangriff hatten ?

Autor: neuer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die aussage der falschrechnerei ist reine absicht um dem militär eine 
angeblich sicherere sache von einem anderen anbieter den vorrang zu 
geben.

hoch lebe die bestechung.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Neuer

Naja, deine Meinung liest sich nicht so, als ob du dir den Beitrag 
angehört hast.

"Wir", die kleinen Hörer des DLF, hätten sowieso andere Probleme, wenn 
wir auf Einkaufstour für eine Abwehrrakete gehen müssen. Dass uns einer 
mit einem solchen Beitrag die Patriot schlecht reden könnte, ist da das 
kleinste Problem.

BTW. Dann könnte man eher darauf verweisen, dass die Patriot mit einem 
per Lochkarten gesteuerten Automaten in Wire-Wrap-Technik aufgebaut ist 
(war) ;-)
http://www.cs.uiowa.edu/~jones/cards/collection/i-...

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.