Anzeige:

Rechenfehler Fließkomma-Berechnung

Hier finden sie die archivierten Beiträge des alten PHPBB Forums von www.loetstelle.net

Rechenfehler Fließkomma-Berechnung

Von Daedalus am 26.03.2010 17:30

Hi Leute!

Sitze gerade wieder einmal leicht verwirrt beim AVR-Programmieren. Folgender Versuch: Übertragen des ADC-Ergebnisses per UART an den PC. Erstaunlich einfach bis hier her. Bis ich dann dahinter kam, dass das Rechenergebnis nicht stimmen kann. Vlt. Bin ich auch einfach zu verwöhnt vom Programmieren am PC. Folgender Auszug:

1]
ADCSR = 0b11000101;


while ( ADCSR & (1<<ADSC)) {;}

i = ADCH;

j = (5000/255) * i; //Ergebnis in mV

k = j; // "Umwandlung" von float auf integer

uart_puts(itoa( k, s, 10 )); // übertragen über uart
uart_putcrlf(); // Carriage Return/ Linefeet über Uart übertragen
1]

Das Problem was sich ergibt, ist dass anscheinend die Nachkommastelle bei der Berechnung vernachlässigt wird. Ich hab' mir nämlich testweise auch das Ergebnis des ADC direkt ausgeben lassen und wenn ich den ADC-Wert 2 eingestellt hab mit dem Poti war das "Umrechnungsergebnis" 38 obwohl (5000/255) * 2 ja 39,2 daher 39 sein müsste. Die "große" Frage ist nur warum? ;)

Danke im Voraus

lg

Re: Rechenfehler Fließkomma-Berechnung

Von derguteweka am 26.03.2010 17:50

Moin,

Daedalus hat folgendes geschrieben:
Die "große" Frage ist nur warum? Wink


Bei deinem codeschnipsel fehlen leider die Variablendeklarationen, also weiss keiner, was i,j,k fuer Typen sind - also ob integer, float oder sonstwas.
Ich vermute aber mal, dass die Rechnung 5000/255 als Integerarithmetik ausgefuehrt wird. Da kaeme in floatingpoint ja 19.6078... raus. In Integer kommt aber nur 19 raus. Die 19 wird dann mit i multipliziert, und das gibt dann 38 und nicht wie gewuenscht 39.2.

Gruss
WK

Re: Rechenfehler Fließkomma-Berechnung

Von Daedalus am 26.03.2010 17:54

derguteweka hat folgendes geschrieben:
Moin,

Daedalus hat folgendes geschrieben:
Die "große" Frage ist nur warum? Wink


Bei deinem codeschnipsel fehlen leider die Variablendeklarationen, also weiss keiner, was i,j,k fuer Typen sind - also ob integer, float oder sonstwas.
Ich vermute aber mal, dass die Rechnung 5000/255 als Integerarithmetik ausgefuehrt wird. Da kaeme in floatingpoint ja 19.6078... raus. In Integer kommt aber nur 19 raus. Die 19 wird dann mit i multipliziert, und das gibt dann 38 und nicht wie gewuenscht 39.2.

Gruss
WK


Sry WK,.. mein Fehler hier das Gesammte mal:

Code:


int main (void)
{

   char s[7];
    int i = 0;
   int k = 0;

   float  j = 0;


   DDRD = 0b11111111;
   DDRC = 0b00000000;

   //USART enable TX :)

   UCSRB |= (1<<TXEN);  // UART TX einschalten
     UCSRC |= (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1
 
     UBRRH = UBRR_VAL >> 8;
     UBRRL = UBRR_VAL & 0xFF;

   UCSRB |= (1<<TXEN);

   ADCSR = 0b10100101;
   ADMUX = 0b00100000;

   while(1)
   {
      ADCSR = 0b11000101;
      

      while ( ADCSR & (1<<ADSC)) {;}

      i = ADCH;

      j = (5000/255) * i;

      k = j;
      

      uart_puts(itoa( i, s, 10 ));

      uart_putcrlf();

      uart_puts(itoa( k, s, 10 ));

      uart_putcrlf();
   }

   return 1;
}



Ich hab schon daran gedacht das j ein float sein muss um die Nachkomma-Stelle zu berücksichtigen aber vlt mach ich auch bei der Initialisierung was falsch, bin nicht mehr so sattelfest in C Very Happy

lg

Re: Rechenfehler Fließkomma-Berechnung

Von derguteweka am 26.03.2010 18:08

Moin,

Ja, hab's hier grad mal ausprobiert, das laeuft so, wie ich mir gedacht hab': Die 5000/255 werden als Integerwert interpretiert.
Schreib' statt (5000/255) lieber (5000.0/255.0) Damit wird der compiler mit der Nase draufgestossen, dass du Floatingpointwerte meinst, und keine Integer.
Aber nachdem Floatingpoint Arithmetik auf schwachbruestigen µCs eh' nicht schoen ist - schneller wird die Rechnung wahrscheinlich so gehen:

k= ((1000*i)+25)/51;

wenn deine Integer gross genug sind, um 1000*i zu verdauen. Wenn nicht, muss man halt noch bisschen mehr nachdenken...

Gruss
WK

Von Daedalus am 26.03.2010 18:14

Hi!

Danke Vielmals jetzt stimmts,...



Zitat:

Damit wird der compiler mit der Nase draufgestossen, dass du Floatingpointwerte meinst, und keine Integer.


Das ist wohl eher der Wink mit dem Zaunpfahl und ich versteh' auch nicht ganz warum aber wenn mans weiß kann man ja immer ein '.0' anhängen Very Happy

Dank nochmals

lg

Von derguteweka am 26.03.2010 18:21

Moin,

Daedalus hat folgendes geschrieben:
Das ist wohl eher der Wink mit dem Zaunpfahl und ich versteh' auch nicht ganz warum aber wenn mans weiß kann man ja immer ein '.0' anhängen Very Happy


Kernighan/Ritchie in Kap2.3 hat folgendes geschrieben:
Eine ganzzahlige Konstante wie 1234 hat den Typ int. ... Gleitpunktkonstanten enthalten einen Dezimalpunkt (123.4) oder einen Exponenten (1e-2) oder beides,...


Und die beiden muessen's ja schliesslich wissen Very Happy

Gruss
WK

Von Daedalus am 26.03.2010 18:23

Kernighan/Ritchie in Kap2.3 hat folgendes geschrieben:
Eine ganzzahlige Konstante wie 1234 hat den Typ int. ... Gleitpunktkonstanten enthalten einen Dezimalpunkt (123.4) oder einen Exponenten (1e-2) oder beides,...



Überzeugt Danke Very Happy

Anzeige: