Forum: Mikrocontroller und Digitale Elektronik AVR int Division


von Michael S. (michi_s)


Lesenswert?

Hallo zusammen,

ich habe hier ein kleines Verständnisproblem bei der Division zweier 
vorzeichenbehafteter Integer Konstanten und der anschließenden 
Multiplikation mit dem Faktor 2^12. Ich erhalte nur dann das korrekte 
Ergebnis, wenn ich entweder a, oder b, oder beide Konstanten vor der 
Division als float caste. Ich versteh einfach nicht, warum das so ist. 
Wäre super, wenn mir hier wer auf die Sprünge helfen könnte.
Als Controller kommt ein Atmega32A zum einsatz.
1
int a = 19186;
2
int b = 17174;
3
int c = 0;
4
5
c = (int)(((float)a/b - 1)*4096);  //geht
6
c = (int)((a/b - 1)*4096);  //geht nicht

: Bearbeitet durch User
von klaus (Gast)


Lesenswert?

Int / int = int

Bei a/b kommt ne 1 raus.

Ist einer der beiden float wird float dividiert.

Gruss

von Michael S. (michi_s)


Lesenswert?

Ahhh, klar, das macht Sinn!
Danke für die schnelle Antwort

von Pandur S. (jetztnicht)


Lesenswert?

Man sollte hier auf Float verzichten und bei integer bleiben. Einfach so 
umformen, dann man nur minimal verliert.

c : = (a/b - 1 ) * 4096
c : = ((4096 * a) div b) - 4096
c : = (a shl 12) div b - (1 shl 12)

von Bernd K. (prof7bit)


Lesenswert?

Jetzt Nicht schrieb:
> Man sollte hier auf Float verzichten und bei integer bleiben. Einfach so
> umformen, dann man nur minimal verliert.
>
> c : = (a/b - 1 ) * 4096
> c : = ((4096 * a) div b) - 4096
> c : = (a shl 12) div b - (1 shl 12)

Aber nicht vergessen vorher auf int32 zu casten denn beim AVR ist int 
nur 16 bit und 16 bit reichen nicht bei so großen Zahlen.

von Amateur (Gast)


Lesenswert?

Das Ganze ist im Übrigen kein AVR-Problem, sondern eine ganz normale 
Eigenschaft der Ganzzahlarithmetik.

Da ist 1000 / 600 immer 1.

Üblicherweise behilft man sich, vor allem bei "längeren" Berechnungen 
damit die Werte - vorübergehend - zu erhöhen. Wichtig ist hierbei, dass 
man den möglichen Bereich nicht überschreitet.
1000  600 ist in der Zwischenrechnung mit 10000  600 = 16

Ein weiterer Trick ist die Berechnung so umzustellen, dass die 
Divisionen an anderer Stelle stattfinden.
Dann wird: (1000 / 600) * 100 über (1) * 100 = 100
zu (1000 * 100) / 600 ==> 100000 / 600 = 166

von Später (Gast)


Lesenswert?

Bernd K. schrieb:
> Jetzt Nicht schrieb:
>> Man sollte hier auf Float verzichten und bei integer bleiben. Einfach so
>> umformen, dann man nur minimal verliert.
>>
>> c : = (a/b - 1 ) * 4096
>> c : = ((4096 * a) div b) - 4096
>> c : = (a shl 12) div b - (1 shl 12)
>
> Aber nicht vergessen vorher auf int32 zu casten denn beim AVR ist int
> nur 16 bit und 16 bit reichen nicht bei so großen Zahlen.

Jetzt Nicht

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.