www.mikrocontroller.net

Forum: Compiler & IDEs Floating Point, Mantisse, Exponent - Beispiele?


Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
http://de.wikipedia.org/wiki/Gleitkommazahl

Wie geht man mit floating point Variablen um? Werden die Zahlen 
normiert? Kann man auf den Exponenten direkt zugreifen?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gast schrieb:

> Wie geht man mit floating point Variablen um?
const double pi = 3.1415926;

double area(double r)
{
  return 4 * pi * r * r;
}

> Werden die Zahlen
> normiert?

Ja, außer ganz kleine Zahlen (und ganz große auch? bin ich mir
gerade nicht sicher), die werden denormiert gespeichert, damit man
sie überhaupt noch darstellen kann.

> Kann man auf den Exponenten direkt zugreifen?

Nein, nicht ohne Tricks[*], warum auch?

[*] Bei 32-bit-Gleitkomma belegt der Exponent ja genau ein Byte,
da könnte man ihn durch Überlagern einer union extrahieren.  Bei
64-bit-Gleitkomma geht das auch nicht mehr.

Es gibt die Funktion frexp() in der math-Bibliothek, die einem
Mantisse und Exponent separiert.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Wie geht man mit floating point Variablen um?

Man überlässt es dem Compiler bzw. der mathe-lib, damit zu rechnen.

>Werden die Zahlen normiert?

Ja

>Kann man auf den Exponenten direkt zugreifen?

Klar. Caste den float in einen unsigned int passender Größe, und 
maskiere die entsprechenden Bits aus, dann noch etwas shiften, schon 
hast du Exponent und Mantisse.

Bleibt die Frage:

Was hast du eigentlich vor?

Oliver

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver schrieb:

> Klar. Caste den float in einen unsigned int passender Größe, und
> maskiere die entsprechenden Bits aus, dann noch etwas shiften, schon
> hast du Exponent und Mantisse.

Nein.  Du hast den ganzzahligen Wert oder dessen unsigned-Darstellung
(wenn er negativ war), so, wie du es beschrieben hast.  Anders als
bei Ganzzahlen bewirkt ein typecast bei Gleitkommazahlen eine echte
Typumwandlung, nicht nur ein Uminterpretieren des Bitmusters.  (Selbst
bei Ganzzahlen erfolgt dieses Uminterpretieren nur beim typecast
zwischen signed und unsigned.)

Autor: Martin Cibulski (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man müsste einen Pointer umcasten, dann könnte man auf das Bitmuster 
direkt zugreifen.

Etwa so:

unsigned long lVar;
float         fVar = 1.234;

lVar = *((unsigned long*)&fVar);


Gruß,
Martin Cibulski

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In C (C99) liefert die Funktion

  m = frexp(x, e)

für die Zahl x die Mantisse m und den ganzzahligen Exponenten e so dass

  x = m * 2**e    und   0.5 <= |m| < 1

ist.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach, das hat ja Jörg oen schon geschrieben.

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch schrieb:

>> Kann man auf den Exponenten direkt zugreifen?
> Nein, nicht ohne Tricks[*], warum auch?

Der von Martin beschrieben Pointer-cast funktioniert (was man wohl als 
Trick bezeichnen kann). Der Grund fuer sowas ist einfach: Moeglichst 
verlustarme Transformierung in andere Zahlenformate.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Stegemann schrieb:

> Der von Martin beschrieben Pointer-cast funktioniert (was man wohl als
> Trick bezeichnen kann).

Wie ich oben schon schrieb, bedingt: die 11-bittige Mantisse einer
64-bit-Zahl nach IEEE 754 popelst du mit diesem Trick auch nicht
mehr raus, zumindest nicht ohne Nachbearbeitung (maskieren/schieben).

Edit: OK, wofür ein solcher Trick brauchbar sein kann ist, dass man
sich das Bitmuster, das zu einer bestimmten Gleitkommazahl gehört,
mal ansehen kann (gewissermaßen die Zerlegung in Mantisse und
Exponent dann im Gehirn macht).

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch schrieb:
> Peter Stegemann schrieb:

>> Der von Martin beschrieben Pointer-cast funktioniert (was man wohl als
>> Trick bezeichnen kann).
> Wie ich oben schon schrieb, bedingt: die 11-bittige Mantisse einer
> 64-bit-Zahl nach IEEE 754 popelst du mit diesem Trick auch nicht
> mehr raus, zumindest nicht ohne Nachbearbeitung (maskieren/schieben).

Das man das Bitmuster noch gemaess Standard interpretieren und zerlegen 
muss, ist ja wohl klar.

> Edit: OK, wofür ein solcher Trick brauchbar sein kann ist, dass man
> sich das Bitmuster, das zu einer bestimmten Gleitkommazahl gehört,
> mal ansehen kann (gewissermaßen die Zerlegung in Mantisse und
> Exponent dann im Gehirn macht).

seufz. Nur weil du es nicht brauchst, heisst das nicht, dass es fuer 
andere keinen Sinn ergibt, sowas zu machen.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Stegemann schrieb:

> Nur weil du es nicht brauchst, heisst das nicht, dass es fuer
> andere keinen Sinn ergibt, sowas zu machen.

Die Frage des OP war aber: "Kann man auf den Exponenten direkt
zugreifen?"

Aber der meldet sich sowieso nicht mehr, wie's scheint.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Doch, danke für die Hinweise!
Es geht um die Darstellung von physikalischen Größen, ich hatte 
angedacht, eine Art auto-ranging mit Präfixumschaltung zu realisieren.

Man kann natürlich auch einfach den Wert mit den entsprechenden 10er 
Potenzen vergleichen und ggf. den Format-String für printf anpassen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gast schrieb:

> Man kann natürlich auch einfach den Wert mit den entsprechenden 10er
> Potenzen vergleichen und ggf. den Format-String für printf anpassen.

Eindringliche Warnung:
Mach es genau so und vergiss dass ein double intern als 
Mantisse+Exponent gespeichert wird.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gast schrieb:

> Man kann natürlich auch einfach den Wert mit den entsprechenden 10er
> Potenzen vergleichen und ggf. den Format-String für printf anpassen.

Das ist zweifellos die sinnvollste Variante.  Nicht nur, dass sie
nicht von der konkreten Zahlendarstellung abhängig ist, sondern
jemand, der das Programm hinterher liest, kann das sogar noch
verstehen. ;-)

Hier mal ein Schnipsel aus einem real existierenden Programm, in
dem ich sowas schon gemacht habe:
      double f = freq;

      if (f > 1E6)
        {
          fmt_freq[7] = 'M';
          f /= 1E6;
        }
      else if (f > 1E3)
        {
          fmt_freq[7] = 'k';
          f /= 1E3;
        }
      else
        {
          fmt_freq[7] = ' ';
        }
      sprintf(b, fmt_freq, f);
      hd44780_outcmd(HD44780_DDADDR(LCD_LINE1));

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch schrieb:
> Gast schrieb:
>
>> Man kann natürlich auch einfach den Wert mit den entsprechenden 10er
>> Potenzen vergleichen und ggf. den Format-String für printf anpassen.
>
> Das ist zweifellos die sinnvollste Variante.  Nicht nur, dass sie
> nicht von der konkreten Zahlendarstellung abhängig ist, sondern
> jemand, der das Programm hinterher liest, kann das sogar noch
> verstehen. ;-)

Und es wird auch funktionieren.
Ich denke nicht, dass der TO daran gedacht hat, dass der Exponent ein 
Exponent zur Basis 2 ist und nicht zur Basis 10, wodurch seine ganze 
Idee mit direktem Zugriff auf den Exponenten in der angedeuteten 
Problemstellung alles andere als simpel sein würde :-)

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Konnte ich auch nicht, denn die 
http://de.wikipedia.org/wiki/Gleitkommazahl#Intern... kannte 
ich gar nicht :-)

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.