- Labornetzteil AliExpress         
Ergebnis 1 bis 7 von 7

Thema: Float verhindern

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    So schlimm sind Fließkommazahlen auch nicht. Wie lange es braucht, könnte man ggf. im Simulator probieren. Meine Schätzung liegt so bei vielleicht 100-500 Zyklen für das Umwandeln und Multiplizieren. Es hängt aber auch vom µC ab (ein Tiny ist da langsamer). Das 2. Problem ist ggf, das man einmal einiges an Code-größe dazu bekommt.

    Die Idee mit der Multiplication und Shifts ist schon richtig. So wie es aussieht müsste man aber wohl schon auf unsigned long, also einen 32 Bit Datentypen gehen (einen 24 Bit Datentypen unterstützt C nicht direkt, nur die Fließkomma Zahlen sind 24 Bit + Exponent). Das sollte immer noch etwas schneller als mit Fließkommazahlen sein. Bei den 32 Bit Zahlen kann man sich dann ggf. beim Shiften einiges Sparen und das Ergebnis aus den oberen 16 Bit nehmen.

  2. #2
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    21.04.2010
    Beiträge
    356
    Also ich hab in der zwischenzeit bisl gegooglet und wies ausschaut ist der UNterschied schon kraß:
    Hier :http://www.avrfreaks.net/index.php?n...=72923&start=0
    hat einer ein paar tests mit unterschiedlichen Datentypen gemacht und anscheinend hat da ein float schon enorme nachteile und schlägt offensichtlich mit 1876 takten zu buche (vs 86 bei nem 32bit integer).
    Also ich denke das da meine Lösung deutlich besser abschneidet:
    #define MAX 3750
    #define MIN 850
    #define MULTI 4294967296/(RV_MAX-RV_MIN)

    static inline uint16_t to10bit(uint16_t val)
    {
    if(val<MIN) val=0;
    else if(val>MAX) val=max-min;
    else val=val-min;
    uint32_t t=val*multi;
    t=t>>22;
    return (uint16_t)t;
    }
    Ich weis zwar nicht genau wieviel takte das braucht aber weniger als 1800 sinds sicher
    und die genauigkeit ist auf jedenfall ausreichend.

    PS: Mir is klar das man das noch optimieren kann (max-min vorher ausrechnen) aber ich vertraue da in den Compiler da es ja geinlined wird und bereits zur compilezeit bekannt ist.

    MFG Thalhammer

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    67
    Beiträge
    2.435
    Hallo Thalhammer,

    Das geht ganz einfach übers Bruchrechnen.

    x = (n*k1)/k2;

    Anstatt mit
    x = n*0.75;
    rechnest du
    x = (n*3)/4;
    3/4 = 0.75

    Du musst nur erst nachsehen, mit welcher Genauigkeit dein C Zwischenberechnungen ausführt Meist sind es 32-Bit, das Zwischenresultat darf nicht grösser werden. Hinzu kommt noch, dass die entsprechenden Bibliotheken Platz benötigen.
    In meinen MicroController-Projekten der letzten 35 Jahre, findest du nirgends FP-Arithmetik. Allerdings kann es sein, dass z.B. in hundertstel Grad gerechnet wird. Falls nötig, wird dann das Komma bei der Ausgabe "dran gefummelt".

    MfG Peter(TOO)


    Praktisch kannst du damit rechnen, dass Floating-Point-Emulation so in der Grössenordnung Faktor 100 langsamer als Integer ist.
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  4. #4
    Erfahrener Benutzer Roboter Genie Avatar von BMS
    Registriert seit
    21.06.2006
    Ort
    TT,KA
    Alter
    34
    Beiträge
    1.192
    Hallo,
    das "Bruchrechnen" habe ich in meinen Projekten auch verwendet. Der Bruch sollte dabei so weit wie möglich gekürzt werden. Auf möglichen Überlauf hat Peter(TOO) bereits hingewiesen. Zudem muss auch beim Teilen durch große Zahlen beachtet werden, dass aufgrund des ganzzahligen Teilens ohne Rest Genauigkeit verloren gehen kann.

    22 Shifts im obigen Code brauchen ohne Barrel Shifter auch viele Takte. Das Schieben kann auch auf das nächste Vielfache von 8 Bit geschehen, der Zugriff kann dann auf die einzelnen Bytes erfolgen:
    Code:
        //Vorraussetzung: Little Endian
        lsbyte0=*(((uint8_t*)(&variablemit32bit))+0);
        byte1=*(((uint8_t*)(&variablemit32bit))+1);
        byte2=*(((uint8_t*)(&variablemit32bit))+2);
        msbyte3=*(((uint8_t*)(&variablemit32bit))+3);
    Grüße, Bernhard
    "Im Leben geht es nicht darum, gute Karten zu haben, sondern auch mit einem schlechten Blatt gut zu spielen." R.L. Stevenson

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    67
    Beiträge
    2.435
    Hallo Bernhard,
    Zitat Zitat von BMS Beitrag anzeigen
    Zudem muss auch beim Teilen durch große Zahlen beachtet werden, dass aufgrund des ganzzahligen Teilens ohne Rest Genauigkeit verloren gehen kann.
    Da muss man eben optimieren. Den Bruch so klein wie möglich, aber so gross, dass man die benötigte Genauigkeit noch erreicht!
    Aber gefragt wurde nach einem Fehler im Bereich von 1% und das ist eigentlich kein Problem.
    Zitat Zitat von BMS Beitrag anzeigen
    22 Shifts im obigen Code brauchen ohne Barrel Shifter auch viele Takte. Das Schieben kann auch auf das nächste Vielfache von 8 Bit geschehen, der Zugriff kann dann auf die einzelnen Bytes erfolgen.
    Das ist im Allgemeinen aber der Job des Compilerherstellers, dass er optimalen Code erzeugt.

    Bei manchen CPUs ist eine Integermultiplikation schneller als mehrere Left-Shifts.

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.11.2004
    Beiträge
    451
    Zum weiteren Optimieren, sollte man auch noch versuchen den Nenner als eine 2er Potenz zu wählen.

    Der AVR kann zwar multiplizieren, zum Dividieren gibt es aber keinen Befehl. Hier muss also emuliert werden, außer es handelt sich um eine 2er Potenz, dann kann man das Ergebnis einfach nach rechts schieben.

Ähnliche Themen

  1. Relais anziehen beim anstecken verhindern?
    Von Filozof im Forum Controller- und Roboterboards von Conrad.de
    Antworten: 6
    Letzter Beitrag: 18.12.2008, 11:38
  2. mehrfaches Auswerten einer IF/Then Bedingung verhindern
    Von mat-sche im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 30.11.2008, 09:36
  3. Pulsüberschläge gegen Masse verhindern ?
    Von magic33 im Forum Elektronik
    Antworten: 4
    Letzter Beitrag: 17.11.2007, 12:33
  4. HILFE: Ledlauflicht Stacküberlauf verhindern
    Von Matthiasbaue im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 17
    Letzter Beitrag: 06.11.2006, 14:13
  5. Transitor - Teilleiten verhindern
    Von 2H2+O2=2H2O im Forum Elektronik
    Antworten: 4
    Letzter Beitrag: 27.04.2006, 22:35

Berechtigungen

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

Solar Speicher und Akkus Tests