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?
Gast schrieb:
> Wie geht man mit floating point Variablen um?
1 | const double pi = 3.1415926; |
2 | |
3 | double area(double r) |
4 | {
|
5 | return 4 * pi * r * r; |
6 | }
|
> 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.
>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
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.)
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
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.
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.
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).
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.
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.
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.
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.
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:
1 | double f = freq; |
2 | |
3 | if (f > 1E6) |
4 | {
|
5 | fmt_freq[7] = 'M'; |
6 | f /= 1E6; |
7 | }
|
8 | else if (f > 1E3) |
9 | {
|
10 | fmt_freq[7] = 'k'; |
11 | f /= 1E3; |
12 | }
|
13 | else
|
14 | {
|
15 | fmt_freq[7] = ' '; |
16 | }
|
17 | sprintf(b, fmt_freq, f); |
18 | hd44780_outcmd(HD44780_DDADDR(LCD_LINE1)); |
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 :-)
Konnte ich auch nicht, denn die http://de.wikipedia.org/wiki/Gleitkommazahl#Interne_Darstellung kannte ich gar nicht :-)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.