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
<< intTmp = 100000 / 1024; (2^16 = 65.536 < 100.000) Versuchs mal mit long int.
>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
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);
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.
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; |
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?
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.
Danke mal für die Hilfe. Ich werde nun versuchen die Sache umzusetzten. Gruss Arni Blackcorner
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.
>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.
.....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.
>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 ?
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.
@ 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.