Float anschauen

Gast #3362239
Lesenswert?

Hallo, ich möchte mir die innere Zahlendarstellung von float und 
double anschauen.

(Mein ATtiny84 kennt kein printf, ich habe nur ein kleines LC-Display)
Wie kann ich eine float absichtlich falsch in eine unsigned long 
Variable casten, um mir das in HEX anzeigen zu lassen?
Gast #3362598
Lesenswert?

casten und unions sind beide standardkonform, aber genau wie memcpy sind 
sie alle undefined behaviour. Das ergibt sich allein schon daraus dass C 
den Aufbau von floats nicht definiert. Sie sollten aber "zufällig" im 
GCC funktionieren...
Und falls der Compiler das memcpy nicht wegoptimiert kriegt ist das 
außerdem extrem ineffizient.
Gast #3362931
Lesenswert?

Dr. Sommer schrieb:
> casten und unions sind beide standardkonform, aber genau wie memcpy sind
> sie alle undefined behaviour. Das ergibt sich allein schon daraus dass C
> den Aufbau von floats nicht definiert.

Der Aufbau von float und der Aufbau von unsigned long. Erst die 
Kombination der beiden macht es undefiniert. Laut ISO C ist es nämlich 
durchaus erlaubt, ein beliebiges Objekt, also auch einen float, per 
memcpy in ein Array aus unsigned char zu kopieren, um auf diese Weise 
die Byte-Repräsentation zu bekommen.

> Und falls der Compiler das memcpy nicht wegoptimiert kriegt ist das
> außerdem extrem ineffizient.

Dann ist aber auch der Compiler extremer Murks.
gcc muß es noch nicht mal wegoptimieren, da es eh komplett im Compiler 
implementiert ist. Das heißt, daß es selbst bei ganz ausgeschalteten 
Optimierungen nicht zu einem Funktionsaufruf kommt.

Ich habe mal folgende 3 Varianten verglichen:
1
static inline unsigned long a(float f)
2
{
3
    return *(unsigned long*)&f;
4
}
5

6
static inline unsigned long b(float f)
7
{
8
    unsigned long ret;
9
    memcpy(&ret, &f, sizeof ret);
10
    return ret;
11
}
12

13
static inline unsigned long c(float f)
14
{
15
    union
16
    {
17
        float f;
18
        unsigned long u;
19
    } uf;
20

21
    uf.f = f;
22
    return uf.u;
23
}

Auf avr-gcc mit -O3 kommt bei allen drei exakt das gleiche raus. Bei dem 
für x86-64 ist die union-Variante eine Instruktion länger. Alles andere 
ist aber auch da gleich.
Was man hier aber schon sieht, ist daß vom Source-Code her die 
union-Variante irgendwie nach "von hinten durch die Brust in Auge" 
aussieht.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren