16 Bit Multiplikation

Gast #3459531
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.
Gast #3459540
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

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