2013-08-16 10 views
6

Chcę przekonwertować liczbę zmiennoprzecinkową na przykład 2.45 na 4-bajtową tablicę znaków. , więc 2.45 powinno wyglądać tak, jak '@' 'FS' 'Ì' 'Í', które jest binarnie reprezentowane przez toee 2.45 = 01000000 00011100 11001100 11001101?Jak przekonwertować float na 4-bajtowe znaki w C?

Rozwiązałem problem, ale ma on bardzo złożony charakter. czy masz jakieś dobre pomysły?

Dzięki za dobre odpowiedzi.

Czy możesz mi powiedzieć, w jaki sposób powrócić z tablicy znaków do liczby zmiennoprzecinkowej?

+2

Co powiesz na 'char a [sizeof_float]; memcpy (char_array, & the_float, sizeof_float) '? –

+2

'' Ì'' i ''Í'' to tylko reprezentacja' 11001100 11001101' w jednym zestawie znaków. – glglgl

Odpowiedz

7

Masz kilka sposobów robienia tego, w tym te dwa:

  1. Zastosowanie rzutowania i wskazówek:

    float f = 2.45; 
    char *s = (char *) &f; 
    

    zauważyć, że nie jest w żaden sposób bezpieczny i że po "łańcuchu" nie ma terminatora znaków.

  2. Użyj union: Tablica char można teraz uzyskać

    union u 
    { 
        float f; 
        char s[sizeof float]; 
    }; 
    
    union u foo; 
    foo.f = 2.45; 
    

    aby uzyskać wartości bajtów. Zauważ również, że jako pierwsza alternatywa nie ma terminatora znaków.

+0

"to faktycznie wykorzystuje niezdefiniowane zachowanie" - czy mógłbyś to wyjaśnić dalej? – Jimbo

+2

'memcpy()' jest preferowany w stosunku do obu twoich podejść. (Nawiasem mówiąc, pierwsza metoda jest "bezpieczna", dopóki wskaźnik aliasingu jest (podpisany lub niepodpisany) 'char *' .A druga metoda nie wywołuje UB. –

+0

@ Jimbo Pamiętaj, że wszyscy członkowie '. union' dzieli tę samą pamięć, co oznacza, że ​​możesz niezawodnie zdobyć wartość ostatniego ustawionego elementu.Jeśli ustawię element 'f' w moim przykładzie, powinienem dostać tylko' f' po tym, dopóki nie ustawię innego elementu. Inaczej nie jest nieokreślone, ale może powodować nieoczekiwane wartości: –

13

Wystarczy użyć memcpy:

#include <string.h> 

float f = 2.45f; 
char a[sizeof(float)]; 

memcpy(a, &f, sizeof(float)); 

Jeśli wymagają odwrotny endianness to jest to błaha sprawa, aby odwrócić bajty a potem, na przykład

int i, j; 

for (i = 0, j = sizeof(float) - 1; i < j; ++i, --j) 
{ 
    char temp = a[i]; 
    a[i] = a[j]; 
    a[j] = temp; 
} 
+0

i jak mogę zmienić endian? – 12oni

+1

@ 12oin 'tmp = a [0]; a [0] = a [3]; a [3] = tmp; tmp = a [1]; a [1] = a [2]; a [2] = tmp; 'aby zmienić endian. – nos