Wie werden Zahlen mit Dezimalpunkt in einer MCU behandelt?


8

Bitte sagen Sie mir, wie MCUs mit Dezimalzahlen wie '23 .3 ',' 3.24 'usw. umgehen. Wie wird es in einem Speicherregister gespeichert? Ich weiß, dass ich beim Umgang mit diesen Zahlen beim Programmieren den Datentyp float verwenden muss. Aber tatsächlich, was passiert in einer MCU, während diese Typen behandelt werden. Sagen Sie mir auch, wie MCUs ohne FPU-Einheit mit dem Float-Datentyp umgehen.

Antworten:


13

Zahlen in typischen Mikrocontrollern haben überhaupt keine Dezimalstellen. Sie sind binäre ganze Zahlen. In der Maschine wird keine Dezimalstelle verwendet. Mit dem Compiler oder Assembler können Sie möglicherweise Konstanten auf diese Weise angeben, diese werden jedoch in Binärdateien konvertiert, bevor der Computer sie sieht.

Sie können jedoch für die ganzzahligen Werte entscheiden, welche Einheiten Sie möchten. Angenommen, Sie möchten Dollars in einem Mikro darstellen. Es kann nicht von Haus aus 3,21 Dollar machen, aber es könnte 321 Cent machen. Das Mikro arbeitet nur mit dem Wert 321, aber Sie wissen, dass es Einheiten von 1/100 Dollar darstellt.

Dies ist nur ein Beispiel, um das Konzept beliebiger Einheiten zu veranschaulichen. Oft werden Zahlen mit mehreren binären Bruchbits dargestellt. Das ist gleichbedeutend damit jede Zählung mit einem Wert von 2 für -N , wobei N die Anzahl der Teilbit ist. Diese Darstellung wird als "Festpunkt" bezeichnet. Sie entscheiden im Voraus, wie viel Auflösung Sie benötigen, und tun so, als ob sich rechts vom imaginären Binärpunkt genügend Bits befinden, um diese Auflösung zu unterstützen. Angenommen, Sie müssen etwas mit einer Auflösung von mindestens 1/100 darstellen. In diesem Fall würden Sie mindestens 7 Bruchbits verwenden, da 2 7 = 128. Das ergibt tatsächlich eine Auflösung von 1/128.

Die Maschine hat keine Ahnung, dass dies geschieht. Diese Zahlen werden als normale Ganzzahlen addiert und subtrahiert, aber alles funktioniert immer noch. Es wird etwas schwierig, wenn Sie Festpunktwerte multiplizieren und dividieren. Das Produkt zweier Festpunktwerte mit N Bruchbits hat 2N Bruchbits. Manchmal behalten Sie einfach die Tatsache im Auge, dass die neue Zahl 2N Bruchbits enthält, oder manchmal verschieben Sie sie um N Bits nach rechts, um zur gleichen Darstellung wie zuvor zurückzukehren.

Gleitkomma ist dasselbe, aber die Anzahl der Bruchbits wird zusammen mit dem ganzzahligen Teil gespeichert, damit diese Anpassung zur Laufzeit vorgenommen werden kann. Das Ausführen von mathematischen Operationen an Gleitkommazahlen kann eine Reihe von Zyklen dauern. Gleitkomma-Hardware erledigt dies alles für Sie, damit die Vorgänge schnell abgeschlossen werden. Die gleichen Manipulationen können jedoch auch in der Software durchgeführt werden. Es gibt keinen Grund, warum Sie keine Unterroutine schreiben können, um zwei Gleitkommazahlen hinzuzufügen, nur dass dies viel länger dauern würde als dedizierte Hardware, die dasselbe tut.

Ich habe ein 3-Byte-Gleitkommaformat für 8-Bit-PICs definiert und eine Reihe von Routinen geschrieben, um sie zu bearbeiten. Mikrocontroller verarbeiten normalerweise reale Werte mit einer Genauigkeit von höchstens 10 oder 12 Bit. Mein Gleitkommaformat verwendet 16 Bit Genauigkeit, was für mehrere Zwischenberechnungen ausreicht.

Ich habe auch ein 32-Bit-Format für die 16-Bit-PICs. Dies verwendet ein 16-Bit-Wort für die Mantisse, was die Berechnungen beschleunigt, da diese PICs jeweils mit 16 Bit arbeiten können.

Diese Routinen sind in meiner Version PIC Development Tools enthalten . Überprüfen Sie nach der Installation Dateien mit dem Namen "fp24" im Verzeichnis SOURCE> PIC und "fp32f" im Verzeichnis SOURCE> DSPIC.


Gleitkomma-Standard Es gibt auch einen IBM-Standard, der nur mit der Tendenz herumgespielt hat.
NickHalden

4

Die Festkomma-Arithmetik wird normalerweise zur Durchführung von Bruchberechnungen in MCUs verwendet.

Der Trick besteht darin zu sagen, dass (zum Beispiel) die oberen 16 Bits von a uint32_tvor dem Dezimalpunkt und die unteren 16 nach dem Dezimalpunkt liegen, d. H. Die gespeicherte Ganzzahl ist in 1/2 ^ 16stel. Mit einigen kleinen Einschränkungen funktioniert die reguläre Arithmetik "einfach".

Hier ist eine Übersicht .


Ich stimme für diesen "Übersicht" -Link ab.
0xakhil

3

Sofern Ihre MCU kein DSP mit Gleitkomma-Multiplikator ist, wird alles als 16-Bit-Zahl (oder 8 oder 32, je nach Plattform) gespeichert. Das ist alles, was die eigentliche MCU weiß.

Darüber haben Sie Ihren "C" -Code und C-Compiler. Der Compiler "kennt" verschiedene Datentypen wie char, int, uint, floats, double und so weiter.

Die häufigste Darstellung von Floats auf Hardware ist ein IEEE-Format. Dies trennt die Mantisse vom Exponenten und verwendet zwei 16-Bit-Wörter, um die Informationen zu speichern. Lesen Sie diesen Wiki-Artikel über IEEE-Zahlenformate.

Es ist also der Compiler, der weiß, wo sich die Mantisse und der Exponent befinden, und der die Mathematik darauf anwendet. Denken Sie daran, etwas über Logarithmen zu lernen? Wie haben sie die Mathematik einfacher gemacht, indem sie Leistung hinzugefügt haben, wenn Sie mehrere haben wollten? Nun, der c-Compiler macht etwas Ähnliches mit den Exponnenten und multipliziert die Mantisse, um die Antwort zu berechnen. Für eine Gleitkomma-Multiplikation erstellt der Compiler also Assembler-Code, der die Exponenten hinzufügt und eine Multiplikation der Mantisse durchführt.

Die MCU weiß nichts von der Nummer !!! Laden Sie einen Speicher in ein Register, fügen Sie dem Register einen Speicher hinzu und setzen Sie bei Bedarf das Übertragsflag usw., bis die Multiplikation abgeschlossen ist.

Es ist der C-Compiler und Ihr Code, der das Konzept von Zahlen, Dezimalstellen usw. von der MCU "abstrahiert".

Nebenbei bemerkt, einige Sprachen unterstützen auch den Datentyp "dezimal", der für Finanzsysteme nützlich ist - auf eingebetteten Plattformen nicht üblich, da Floats weniger Speicher benötigen und eine effiziente Leistung erbringen.


1

Auf die gleiche Weise verarbeiten vollwertige Prozessoren ohne fpu (z. B. die meisten ARMs) Gleitkommawerte. Mit einer Software fpu. Es gibt eine Bibliothek, die die mathematischen / bitweisen Operationen ausführt. Wenn Sie sich daran erinnern, in der Grundschule mit Bleistift und Papier Addition, Multiplikation usw. durchgeführt zu haben, hat sich an dem Tag, an dem Sie von ganzen Zahlen zu Zahlen mit Dezimalpunkt gewechselt sind, nicht viel geändert. Sie haben die gleiche Berechnung durchgeführt, indem Sie entweder die Zahlen so anpassen mussten, dass die Dezimalstellen vor dem Start (Addition und Subtraktion) oder nach dem Ende (Multiplikation oder Division) ausgerichtet waren. Hard- und Soft-FPUS unterscheiden sich nicht. Sie passen die Bits vor und nach der Operation an, aber die Operation ist im Grunde eine Ganzzahloperation.

Ich erinnere mich nicht genau, wo ich es jetzt finden kann, aber Texas Instruments hatte ein sehr gutes Dokument in Bezug auf ihre DSP-Produkte. Es erklärte ihr Gleitkommaformat und ging so weit zu erklären, wie die Operationen funktionierten. Ihr Format hat keine Rundungen und Denormale und keine Unendlichkeit und keine leisen und signalisierenden Nans wie IEEE, daher ist es viel einfacher zu verstehen und wesentlich schneller als IEEE-Formate. Sobald Sie dieses Format in Aktion gesehen haben, haben Sie Ihren ersten Schritt in Richtung des IEEE-Formats getan. Das Runden erfordert einige Erklärungen und Überlegungen, aber der Rest, die Grundlagen von Zeichen, Exponent und Mantisse, sind dieselben.

Es ist sehr teuer, ressourcenmäßig (Speicher, Flash, CPU-Zyklen), Soft-Float-Bibliotheken zu verwenden, und ich würde davon in einem eingebetteten System oder Mikrocontroller abraten. 12.3 und 24.5 sind recht einfach zu verwalten, beispielsweise als Ganzzahlen 123 und 245, solange Sie sich erinnern oder wenn Sie sicherstellen, dass alle zugehörigen Berechnungen verstehen, dass die Zahlen alle mit zehn multipliziert werden und wenn / wenn Sie a anzeigen Benutzer bei dieser Konvertierung fügen Sie den Dezimalpunkt hinzu. Spart Tonnen von Code und Leistung. Natürlich ist die Ganzzahldivision bei Mikrocontrollern und eingebetteten Systemen eine schlechte Sache, da die meisten Prozessoren keinen Divisionsbefehl haben, und dies schließt die Division durch 10 ein, um sie in Dezimalzahlen umzuwandeln und dem Benutzer anzuzeigen. Und die gleiche Antwort, die Unterteilung, die Sie von Ihrem C-Code erhalten, erfolgt mithilfe einer Bibliothek.


0

Gleitkommazahlen werden im binären 32-Bit-Format gespeichert, und das erste Bit gibt an, ob der Gleitkommawert eine Pos / Neg-Zahl ist. Die nächsten 8 Bits sind der Exponent -127. Dann gibt es 23 Bits, die die vollständige Zahl einschließlich der Dezimalstelle sind, d. H. :
1 00010001 00010001000000000000000
Also 1 ist, dass es negativ ist, die nächsten 8 Bits sollen in diesem Fall den Exponenten anzeigen:
0001 0001 = 17 (17-127 = -110)
Dann wird die Mantisse geteilt:
(1+1/4+1/128)2^5

2^5war die Bewegung der Dezimalstelle, als der Gleitkommawert auf binär verschoben wurde. Das Ergebnis verliert beim Konvertieren einige Ziffern, aber sie sind nahe beieinander. 1.5ex10-110
Ich habe möglicherweise Fehler gemacht, als ich anderen gefolgt bin, aber dies ist die allgemeine Idee, wie Floats im Speicher gespeichert werden.


2
Dieser Beitrag enthält möglicherweise Spuren von Informationen, ist jedoch in einer unformatierten Textwand für Chat-Nachrichten versteckt. Stack Exchange ist nicht Facebook. Versuchen Sie daher, eine professionellere Sprache zu verwenden, und verwenden Sie die zur Verfügung gestellten Formatierungswerkzeuge, um die Informationen lesbar zu machen, beginnend mit den Absätzen.
Pipe
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.