www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik dsPIC C30 einfache Prozentrechnung


Autor: Mempo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich möchte folgende Berechnung durchführen:

prozent = (100*anzahl)/gesamt;

Leider funktioniert dies nicht und ich habe keine Ahnung woran es liegen 
könnte, vlt. kann jemand von euch helfen.

Gruß Mempo

Autor: Mempo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich zum Beispiel x=(100*3000)/4000; rechne bekomme ich als Ergebnis 
-6 die Variable ist als Integer deklariert.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Wenn ich zum Beispiel x=(100*3000)/4000; rechne bekomme ich als Ergebnis
>-6 die Variable ist als Integer deklariert.

Wenn ein Integer bei deinem uC 16 Bit breit ist hast
du einen Überlauf: 100*3000 = 300000

Autor: Mempo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Antwort so dachte ich mir das auch aber wenn ich die 
Variable zum beispiel als double oder so etwas deklariere bekomme ich 
immer noch ein falsches Ergebnis.


Gruß Mempo

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Danke für die Antwort so dachte ich mir das auch aber wenn ich die
>Variable zum beispiel als double oder so etwas deklariere bekomme ich
>immer noch ein falsches Ergebnis.

Welche Variable hast du als double deklariert? prozent?
Die Rechnung ist dann immer noch falsch.
prozent kriegt nur das Ergebnis zu sehen.


Probier mal:

prozent = (100UL * anzahl) / gesamt;

Autor: Mempo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dankeschön für die Hilfe, kannst du mir vlt. noch sagen was das UL 
hinter der 100 bedeutet?

Gruß Mempo

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sinnvoller wärs vielleicht, dir rechte Seite auch mal als Fließkomma zu 
berechnen...

Autor: Mempo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja das klappt ja jetzt auch alles, nur frage ich mich was das UL 
bedeutet.

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
'unsigned long'.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ja das klappt ja jetzt auch alles, nur frage ich mich was das UL
>bedeutet.

Das UL macht aus der 100 ein unsigned long.
Das Ergebnis der Multiplikation ist dann auch
ein unsigned long. 300000 passt somit in das Ergebnis.
Lässt man das UL weg ist die 100 ein int.
Das Ergebnis der Multiplikation somit auch ein
int weil vermutlich auch anzahl ein int oder unsigned int ist.
int geht aber nur bis 32768. unsigned int bis 65535.
300000 passt also nicht in das Ergebnis der Multiplikation
von int/unsigned int.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>int geht aber nur bis 32768. unsigned int bis 65535.

Bevor jemand meckert:
Ein int ist nicht immer 16Bit breit.
Auf 32Bit uC ist ein int auch meist 32 Bit.
int kann aber auch 64Bit sein.

Autor: Mempo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay danke für den kleinen C Nachhilfekurs, ist diese Schreibweise in 
Programmen gebräuchlich oder ist es eleganter vorher den richtigen Typ 
festzulegen?

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Okay danke für den kleinen C Nachhilfekurs, ist diese Schreibweise in
>Programmen gebräuchlich oder ist es eleganter vorher den richtigen Typ
>festzulegen?

Wenn prozent, anzahl, gesamt jeweils in ein int passen
dann ist das mit den 100UL besser. Dann wird nur diese
eine Berechnung als unsigned long ausgeführt. Machst du
prozent, anzahl, gesamt zu unsigned long dann belegen
sie doppelt soviel RAM falls ein int 16Bit ist.

Autor: Mel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und was ist jetzt mit dem Überlauf?

Angenommen 32Bit Prozessor, wenn ich eine Prozentrechung habe:
kann man natürlich auch auf einen 16- oder 8- Bitter haben,
dann halt long durch short bzw. char ersetzen.

char Prozent(long lAkt, long lGes)
{

   unsigned long ulAkt,ulGes,ulRet;
   if(lAkt< 0)
   {
     ulAkt= (~lAkt);
   }else{
     ulAkt= (lAkt);
   }
   if(lGes< 0)
   {
     ulGes= ~lGes;
   }else{
     ulGes= (lGes);
   }

    if(ulGes == 0)
    {
        return 0;
    }
    else
    {
       ulRet = (ulAkt*100) / ulGes;
    }

    if(ulRet > 0xFF)
    {
        return 0xFF;
    }
    else
    {
        return (uint8)ulRet;
    }
}

int main(void) {
    char cPercent = 0;
    long lAkt = 0;
    long lGes = 0;


    //(1)Testfall 1: MIN_INT32,MIN_INT32 ergibt 0 statt 100 \n");
    lAkt = INT_MIN;
    lGes = INT_MIN;
    cPercent = Prozent(lAkt, lGes);

return 0;
}


MfG
Mel

Autor: Bertram S. (bschall)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ein cast kann auch Wunder bewirken...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.