Forum: Mikrocontroller und Digitale Elektronik dsPIC C30 einfache Prozentrechnung


von Mempo (Gast)


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

von Mempo (Gast)


Lesenswert?

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

von holger (Gast)


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

von Mempo (Gast)


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

von holger (Gast)


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;

von Mempo (Gast)


Lesenswert?

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

Gruß Mempo

von Sven P. (Gast)


Lesenswert?

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

von Mempo (Gast)


Lesenswert?

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

von Sven P. (Gast)


Lesenswert?

'unsigned long'.

von holger (Gast)


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.

von holger (Gast)


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.

von Mempo (Gast)


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?

von holger (Gast)


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.

von Mel (Gast)


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

von Bertram S. (bschall)


Lesenswert?

ein cast kann auch Wunder bewirken...

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.