-         

Ergebnis 1 bis 7 von 7

Thema: Lösen von Überlauf

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    15.06.2008
    Ort
    Wien
    Beiträge
    162

    Lösen von Überlauf

    Anzeige

    Hi,
    Ich habe folgendes Problem und weiß nicht genau wie man es möglichst effizient lösen kann.
    Es gibt eine Funktion die ein int16_t verlangt. Ich rufe sie folgendermaßen auf:
    foo(((int32_t)x<<15)/y);
    das Problem tritt auf, wenn x==y da dann 32768 übergeben wird was natürlich zu einem falschem Ergebnis führt.
    Meine Lösungsversuche sind die:
    foo(((int32_t)x*32767)/y);
    foo(((int32_t)x<<15)/y-1);
    Allerdings bin ich mit beiden Varianten nicht ganz glücklich da sie bei allen anderen Werten zu einem (kleinem) Fehler führen.
    Hat jemand eine schlaue Idee dazu?

    Und meine 2te Frage ist was passiert bei einer Division durch 0 auf einem AVR.
    Mathematisch gesehen ist das ja nicht definiert, aber was passiert im µC?


    LG
    Nothing is impossible, the impossible just takes longer!

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    1) müsste das nicht heissen:
    foo ( (int16_t)( (int32_t)(x << 15) / (int32_t)y ) )

    2)
    ich glaub, das Ergebnis ist "unpredictable". Da es ja keine DIV instruction für den µC gibt, ist der Compiler zuständig, die Division zu generieren UND so einen Check zu machen.
    Am besten den AVR mal in sowas hineinhetzen und mal gucken, ob es wo zu rauchen beginnt *g*
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    15.06.2008
    Ort
    Wien
    Beiträge
    162
    ad 1) nicht unbedingt, da bei mir y ohnehin 32 bit lang ist, und das Gesamtergebnis vor dem Übergeben an die Funktion automatisch gecastet wird.

    ad 2) werd ich probieren

    P.S.: Gratuliere zum 7000endsten Beitrag
    Nothing is impossible, the impossible just takes longer!

  4. #4
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    ahja, das geht dahin, thx *g*

    Den Fall x==y könntest du vorher abfragen.
    Aber was kannst du in diesem Fall der Funktion denn (gültiges) übergeben ?
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    15.06.2008
    Ort
    Wien
    Beiträge
    162
    Ach ja, das hab ich vergessen zu erwähnen. Die Funktion liefert zu jedem Wert im Intervall -32768 bis 32767 einen Wert (die Funktion ist quasi stetig). Daher möchte ich statt 32768 einfach 32767 übergeben.
    Allerdings ist eine if-Schleife mMn das Umständlichste.
    im Moment verwende ich die Multplikation mit 32767 da der Fehler dann insgesamt geringer ist als wenn ich überall 1 abziehe.
    Nothing is impossible, the impossible just takes longer!

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Felix G
    Registriert seit
    29.06.2004
    Ort
    49°32'N 8°40'E
    Alter
    34
    Beiträge
    1.780
    Falls x != y nicht sichergestellt werden kann, wäre ein if allerdings die sauberste Lösung...

    Code:
    int16_t tmp = (x != y) ? (((int32_t)x << 15) / y) : 32767;
    
    foo(tmp)
    So viele Treppen und so wenig Zeit!

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    15.06.2008
    Ort
    Wien
    Beiträge
    162
    So Leute, das Ganze hat sich wohl aufgelöst.
    Ich habe mir die Funktion mal genauer angesehen und bemerkt das mein (x<<15) eigentlich falsch ist da, ohnehin mit 32767 multipliziert werden müsste um 100% richtig zu sein.

    LG
    Nothing is impossible, the impossible just takes longer!

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •