Multiplikation - Ergebnis falsch

Gast #1640025
Lesenswert?

Hallo,

habe ein Mega128 auf dem folgende Multiplikation ein falsches
Ergebnis liefert.

unsigned int x = 0, y = 999;

 x = y * 9

 Ergebnis x = 8910 sollte eigentlich 8991 sein.
 Es fehlen also 9*9 = 81
 Bin echt am verzweifeln. Ich finde den Fehler einfach nicht.
 Hat jemand vielleicht ein Tip wie der Fehler zustande kommt?

Gruß
Gast #1640053
Lesenswert?

Ja, bin ganz sicher das y = 999 sind.

hier noch der ganze Code.


void Out(unsigned int wert)
{
 unsigned int x0 = 0, in = 0, wert1 = 0;//
 signed int diff = 0;

    in = wert;

    itoa(in, cm_buff); // Wert auf Display ausgeben
    wrlcd_ziffK(0);


   if (in > 2424) {
       in = 2424;
   };

   if (in < 1425) {
       in = 1425;
   };

    wert1=(in - 1425);

   itoa(wert1, cm_buff); Wert auf Display ausgeben
   wrlcd_ziffK(1);

    diff = (wert1 - x2); // x2 ist eine Globale Variable

        if (diff > 21 | diff < -21) {

            x_wert = ((x2 + wert1)/2);
            x2 = x_wert;
        }
        else  {

            x3 = x2*9; // !!!!!!!!!!! Hier ist x3 nur 8910 wenn x2 = 999

            itoa(x3, cm_buff); // Wert auf Display ausgeben
            wrlcd_ziffK(0);

            x_wert = (x3 + wert1)/10;

            itoa(x_wert, cm_buff);
            wrlcd_ziffK(1);

            x2 = x_wert;
        };

        itoa(x_wert, cm_buff); // Wert auf Display ausgeben
        wrlcd_cmbuff(1);

}
Gast #1640102
Lesenswert?

Hallo

ja, wert kann 1400 -  2700 sein.

Kurze erklärung zu code.
Ein ziemlich unruhiger wert soll mit dieser Routine
ruhig gestellt werden. D.h. ein wert kommt rein (wert)
durch die ersten beiden If schleifen wird minimal und maximal wert
begrenzt. Anschließend enthät wert1 einen wert von 0-999.
x2 enthält den Wert der beim vorherigem Aufruf ausgegeben wurde.
Beträgt die Differenz zwischen dem alten und dem neuen Wert mehr
als 21 soll nicht so stark geschnitten werden damit sich der Wert
schnell ändert. Ist die Differenz dann kleiner als 21 wird stärker
geschnitten um den Wert ruhig zu bekommen. x2 enthält also immer den
alten Wert. Dieser gewichtet dann mit dem Faktor 9 und der neue Wert mit 
dem Faktor 1, das ganze geteilt durch 10 und der Wert ist schön ruhig.
Angenommen x2 wäre 900 und wert1 wäre 999, müsste nach 10 durchläufen
x_wert = 999 sein. Da aber nach der Multiplikation (x3 = x2*9) nur
8910 anstatt 8991 rauskommen ist der maximal wert von wert1 = 990.
#1640114
Lesenswert?

ghd schrieb:

> Angenommen x2 wäre 900 und wert1 wäre 999, müsste nach 10 durchläufen
> x_wert = 999 sein.

Angenommen ... müsste

Nicht annehmen. Hast du es kontrolliert? Hast du deinem Programm 
zugesehen, wie es rechnet?

> Da aber nach der Multiplikation (x3 = x2*9) nur
> 8910 anstatt 8991 rauskommen ist der maximal wert von wert1 = 990.

Du bist wie ein Arzt, du siehst dir die Smptome an und schliesst daraus 
auf die Ursache.
Du kannst das aber besser machen als ein Arzt. Sieh dir die 
Ausgangswerte und Zwischenergebnisse an! dann brauchst du nicht raten.
Moderator #1640136
Lesenswert?

> Angenommen x2 wäre 900 und wert1 wäre 999, müsste nach 10 durchläufen
> x_wert = 999 sein.

Das ist ein Trugschluss.

Du erwartest, dass x2 mit der zeit gegen x_wert=999 konvergiert, was
aber auf Grund von Rundungsfehlern der Integerdivision nicht passiert.
Bei x2=990 steigt der Wert nicht weiter, weil dann

  (9 * x2 + x_wert) / 10 = (9 * 990 + 999) / 10 = 990.9

ist, was auf 990 abgerundet wird. Damit ist das neue x2 gleich dem alten
x2. x2 kann also nie größer als 990 werden.
#1640168
Lesenswert?

ghd schrieb:
> puh, also ich weiß ja nicht, aber einfach einen Standard sheet
> nehmen, die Routine einfügen und in der main den Aufruf.
> Ein allgemeingültiges Programm für alle µC´s und Compiler zu schreiben
> das einfach per drag & drop in den Compiler kopiert wird u.s.w wird
> schwer.

Und woher sollen wir wissen, wie x2 definiert ist (ok hast du 
nachgereicht). Was ist mit

wrlcd_ziffK(0);
wrlcd_ziffK(1);
wrlcd_cmbuff(1);


wie ist cmd_buf definiert (auch dort könnte ja ein Fehler sitzen)

x2 ist eine globale Variable. Wer garantiert mir, dass nicht einer 
dieser Funktionsaufrufe diese Variable verändert. Wer garantiert mir, 
dass cmd_buf nicht zu klein definiert ist, und der itoa das x2 
niederbügelt?


Du willst Hilfe! Denkst du nicht, das es dann an dir liegt, alles so 
aufzubereiten, dass ich direkt Lust darauf habe, dein Programm einfach 
auszuprobieren. Wenn ich vorher auch noch 50 Syntaxfehler durch 
auskommentieren fixen muss und die Hälfte des Programms dazuerfinden 
muss, nur damit ich es erst mal durch den Compiler kriege, hab ich 
ehrlich gesagt keine allzugroße Lust, genau das zu tun.

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