Forum: Compiler & IDEs 16 Bit Multiplikation


von Martin (Gast)


Lesenswert?

Hi,

ich hab folgenden Code:
1
void SetLightBrightness(uint8_t kanal, uint8_t brightness)
2
{
3
  uint16_t data = 0;
4
5
  [...]//Hier wird data aus einem Array ausgelesen
6
7
  uart_puts("data: ");
8
  uart_putuint16(data);
9
  uart_puts("\n");
10
11
  data = data * brightness / 100;
12
13
  uart_puts("result: ");
14
  uart_putuint16(data);
15
  uart_puts("\n");
16
}

Mein Problem war dann folgendes:
brightness = 50, data = 1307, result = 653.
brightness = 50, data = 1336, result = 12.
Mit 1336 * 50 bin ich über 16bit im Zwischenergebnis. Daher hab ich 
folgendes gemacht:
1
void SetLightBrightness(uint8_t kanal, uint8_t brightness)
2
{
3
  uint16_t data = 0;
4
5
  [...]//Hier wird data aus einem Array ausgelesen
6
7
  uart_puts("data: ");
8
  uart_putuint16(data);
9
  uart_puts("\n");
10
11
  uint32 Math32 = data * brightness / 100;
12
13
  char buffer[12];
14
  itoa(Math32, buffer, 10);
15
  uart_puts("result: ");
16
  uart_puts(buffer);
17
  uart_puts("\n");
18
}

Trotzdem kommen komische Ergebnisse raus, sobald ein Zwischenergebnis 
über 16bit ist - Warum?
Ich hab schon verschiedene Schreibweisen probiert (z.B. alle 
Berechnungen nacheinander), selbes Problem oder falsche Ergebnisse.
Weiß jemand Rat?

Vielen dank schon mal!


Noch ein paar Infos:
Controller ist ein Mega32L8, läuft mit 3,3V @ 8MHz.
AtmelStudio 6.1, Optimization ist auf -Os.

von chris (Gast)


Lesenswert?

Der Compiler wertet erst den rechten Ausdruck aus und schreibt ihn dann 
in die Variable. Dabei ist die Größe der Variable irrelevant. D.h. die 
rechte Seite wird mit 16bit berechnet (weil data 16bit breit ist). Um 
das zu verhindern, musst du dem Compiler explizit sagen, dass er mit 
32bit rechnen soll:

uint32 Math32 = (uint32)data * brightness / 100;

So wandelt der Compiler data in eine 32bit Zahl und führt dann die 
Berechnung in 32bit durch.

lg
Chris

von Kaj (Gast)


Lesenswert?

Oder einfach die Variable Data direkt vom Typ uint32 machen.

von Martin (Gast)


Lesenswert?

Super, danke, das funktioniert! :)

von safety first (Gast)


Lesenswert?

.. oder gleich als uint64 deklarieren.

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.