2009-05-05 7 views
6

Was ist der beste Weg, um ein unsigned Char-Array zu einem Float-Array in C++ zu konvertieren?Casting eines Arrays von unsigned Chars zu einem Array von Floats

Ich habe eine derzeit für Schleife als

for (i=0 ;i< len; i++) 
    float_buff[i]= (float) char_buff[i]; 

folgt Ich muss auch das Verfahren umgekehrt, dh von unsigned char umwandeln würde schweben (float auf 8bit Umwandlung)

for (i=0 ;i< len; i++) 
    char_buff[i]= (unsigned char) float_buff[i]; 

Jede Beratung geschätzt

Danke

+1

Was machst du das erfordert dies? –

Antwort

2

Ihre Lösung scheint richtig, aber auf dem Rückweg könnten Sie die schwebenden Ziffern im Casting verlieren.

+0

Danke Ich bin verwirrt, welche C++ - Stil zu verwenden (neu interpretieren oder statisch), so habe ich nur den alten Stil, Any Ideen. Was passiert auch beim Konvertieren von float zu unsigned char, wenn der Float größer als 255.0 ist. (nicht besorgt über die Ziffern nach dem Punkt) Dank –

+0

Wenn der Schwimmer größer als 255 ist, wird es das MOD-Ergebnis nach der Besetzung haben (wie bei jedem anderen Überlauf). Zum Beispiel: float = 500 -> char = 254. float = 256 -> char = 0. BTW, hier sind ein paar Informationen zu static_cast: http://stackoverflow.com/questions/103512/in-c-why-use-staticcastintx -instead-of-intx –

+0

Das Verhalten, wenn der Gleitkommawert> = 256 ist, ist undefiniert - das Erhalten eines Modulo-Wertes ist zwar häufig, aber nicht garantiert. –

2

Zu welchem ​​Zweck machst du das? Einen Float in einen Char zu schieben macht keinen Sinn. Auf den meisten Plattformen wird ein float 4 Byte sein und eine Fließkommazahl darstellen, wobei ein Zeichen ein 1 Byte ist und oft ein einzelnes Zeichen darstellt. Sie verlieren 3 Bytes an Daten, die versuchen, ein Float in ein Char zu schieben, richtig?

+0

Danke Ich muss von Float zu 8bit konvertieren –

+0

Der Cast wird eine Konvertierung durchführen - den Bruchteil des Floats abschneiden. Dies kann genau sein, was die Person will. Eine wichtige Sache zu beachten ist, dass, wenn der integrale Teil des Floats nicht in einem Zeichen ohne Vorzeichen dargestellt werden kann (in der Regel, wenn es nicht im Bereich 0-255 liegt), ist es nicht definiert. –

+0

Danke Michael, ich habe nichts dagegen, den Bruchteil zu verlieren. Wenn der Float weniger als 255 ist, wird die Besetzung OK? Ich würde das Ergebnis auf 255 begrenzen, wenn der Float größer wäre. Dank –

8

Ihre Lösung ist so ziemlich die beste Option, jedoch würde ich halte zu Schalt:

char_buff[i]= static_cast<unsigned char>(float_buff[i]); 
0

Wenn Sie mit sehr großen Arrays zu tun und die Leistung ist wichtig, dann kann folgendes beweisen etwas effizienter:

float *dst = float_buff; 
    unsigned char *src = char_buff; 

    for (i=0; i<len; i++) *dst++ = (float)*src++; 
+0

Danke Dan, danke für den Tipp –

+0

Oder std :: copy (char_buff, char_buff + len, float_buff); –

+0

Wenn Sie std :: copy hier verwenden, wird ein Fehler in STL (sowie in C++) angezeigt. Wenn Sie eine Kopie von etwas machen, sollte es stimmen, dass copy == original ist. Mit dem impliziten Casting ist dies nicht mehr der Fall, weshalb implizites Casting vermieden werden sollte. –

2

Ihre erste Schleife erfordert keine Besetzung. Sie können implizit von einem Typ (z. B. unsigned char) in einen breiteren Typ (z. B. float) konvertieren. Ihre zweite Schleife sollte static_cast verwenden:

for (i=0; i< len; i++) 
    char_buff[i]= static_cast<unsigned char>(float_buff[i]); 

Wir verwenden static_cast explizit den Compiler zu sagen, um die Umwandlung zu einer engeren Art zu tun. Wenn Sie die Umwandlung nicht verwenden, warnt Ihr Compiler Sie möglicherweise, dass die Konvertierung Daten verlieren könnte. Die Anwesenheit des Darstellers bedeutet, dass Sie verstehen, dass Sie die Datengenauigkeit verlieren könnten und dass Sie damit einverstanden sind. Dies ist nicht ein geeigneter Ort zu verwenden reinterpret_cast. Mit static_cast haben Sie zumindest einige Einschränkungen, welche Conversions Sie durchführen können (z. B. wird es wahrscheinlich nicht möglich sein, eine in eine Nuclear_Submarine* zu konvertieren). reinterpret_cast hat keine solchen Einschränkungen.

Auch hier ist, was Bjarne Stroustrup zu diesem Thema zu sagen hat.

9

Ich denke, der beste Weg, ein Funktionsobjekt zu verwenden ist:

template <typename T> // T models Any 
struct static_cast_func 
{ 
    template <typename T1> // T1 models type statically convertible to T 
    T operator()(const T1& x) const { return static_cast<T>(x); } 
}; 

gefolgt von:

std::transform(char_buff, char_buff + len, float_buff, static_cast_func<float>()); 
std::transform(float_buff, float_buff + len, char_buff, static_cast_func<unsigned char>()); 

Dies ist die lesbar, weil sie sagt, was auf Englisch getan wird: Umwandlung einer Sequenz in einen anderen Typ mit statischen Casting. Und zukünftige Casts können in einer Zeile ausgeführt werden.

1

Die Besetzung erfolgt automatisch, Sie müssen sie also nicht explizit machen.
Aber Sie die Standard-Algorithmen verwenden können:

std::copy(char_buff,char_buff+len,float_buff); 

Konvertierung zurück von float verkohlen ein potenzielles Informationsverlust ist. Du musst also expliziter sein.

std::transform(float_buff,float_buff+len,char_buff,MyTransform()); 

Hier verwenden wir die Klasse MyTransform, die einen Operator haben sollte(), die einen Schwimmer nimmt und gibt ein Zeichen. Das sollte trivial sein.

0

Niemand hat dies erwähnt, aber wenn Sie irgendeine Arithmetik mit den Floats machen, möchten Sie vielleicht runden anstatt zu kürzen ... wenn Sie das Zeichen 49 haben, und es wird in 4.9E1 verwandelt, nach einigen arithmetisch, könnte es sich in 4.89999999E1 verwandeln, was zu 48 wird, wenn Sie es wieder in ein char verwandeln.

Wenn Sie nichts mit dem Float machen, sollte dies kein Problem sein, aber warum brauchen Sie es als Float überhaupt?

Verwandte Themen