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


von Arni Blackcorner (Gast)


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

von Gast (Gast)


Lesenswert?

<< intTmp = 100000 / 1024;

(2^16 = 65.536 < 100.000)

Versuchs mal mit long int.

von Kai G. (runtimeterror)


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?
1
intTmp = ADReadPort(1) * 25 / 256;

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

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

von Arni Blackcorner (Gast)


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

von Karl H. (kbuchegg)


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.

von Johannes M. (johnny-m)


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
1
uint32_t intTmp;
2
3
intTmp = intADW0 * intTmp;
4
//oder
5
intTmp *= intADW0;
In diesem Fall kann man sich den cast (Typkonversion) sparen, weil 
intTmp ja bereits groß genug ist.

Ansonsten wäre es (allgemein)
1
uint16_t a, b;
2
uint32_t c;
3
4
c = (uint32_t)a * b;

von Arni Blackcorner (Gast)


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?

von Johannes M. (johnny-m)


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.

von Arni Blackcorner (Gast)


Lesenswert?

Danke mal für die Hilfe. Ich werde nun versuchen die Sache umzusetzten.

Gruss

Arni Blackcorner

von Stefan B. (stefan) Benutzerseite


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.

von Arni Blackcorner (Gast)


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.

von neuer (Gast)


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.

von Arni Blackcorner (Gast)


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 ?

von neuer (Gast)


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.

von Stefan B. (stefan) Benutzerseite


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-applied.html

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.