2009-05-05 12 views
6

符号なし文字配列をC++の浮動小数点型配列に変換する最適な方法は何ですか?符号なし文字の配列を浮動小数点数の配列にキャストする

私も(8bit換算にフロート)をfloatにunsigned char型からの変換すなわち、手順を逆にする必要が

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

を次のように私は、現在のループのために持って

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

何かアドバイスはなりありがとうございます

ありがとうございました

+1

これは何をしていますか? –

答えて

2

解決策戻ってくる途中で、キャスティングの浮動小数点が失われる可能性があります。

+0

ありがとう 私はどのC++スタイルのキャスト(再解釈または静的)を使用するのか混乱しています。 また、floatが255.0より大きい場合、floatからunsigned charに変換するとどうなりますか? (ポイントの後の数字は心配しないでください) ありがとう –

+0

floatが255より大きい場合、キャスト後のMOD結果は他のオーバーフローと同じになります。例:float = 500 - > char = 254. float = 256 - > char = 0.ここで、static_castの情報をいくつか示します:http://stackoverflow.com/questions/103512/in-c-why-use-staticcastintx -instead-of-intx –

+0

浮動小数点数が256より大きい場合の動作は未定義です - モジュロ値を得ることは一般的ですが、保証されていません。 –

2

どのような目的でこれをやっていますか?フロートを文字に押し込むことは、実際には意味をなさない。ほとんどのプラットフォームでは、浮動小数点数は4バイトになり、浮動小数点数を表します。ここで、charは1バイトになり、しばしば1文字を表します。浮動小数点型をcharに変換しようとすると、3バイトのデータが失われます。

+0

ありがとう floatから8bitに変換する必要があります –

+0

キャストは浮動小数点数の小数部分を切り捨てて変換を実行します。これはまさに人が望むものかもしれません。浮動小数点の整数部分が符号なしの文字で表現できない場合(一般に0〜255の範囲にない場合)、それは未定義です。 –

+0

マイケルありがとう、私は分数の部分を失うことを心配しないでください。 浮動小数点数が255未満の場合、キャストは正常に動作しますか?浮動小数点がこれより大きい場合は、結果を255に固定します。 ありがとう –

8

あなたの解決策はかなりの最良の選択肢である、しかし、私はへの切り替えを検討する:あなたは非常に大きな配列や性能を扱っている場合は

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

その後、次のことが少しより効率的になるかもしれないが不可欠です。

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

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

ありがとうございましたDan、チップをご理解ください –

+0

またはstd :: copy(char_buff、char_buff + len、float_buff); –

+0

ここでstd :: copyを使用すると、STL(C++と同様)の欠陥が公開されます。何かのコピーを作成するときは、copy == originalとなるはずです。暗黙のキャストに頼ることでこれはもはや真実ではないので、暗黙のキャスティングは避けるべきです。 –

2

最初のループにはキャストは必要ありません。 1つのタイプ(例えば、unsigned char)からより広いタイプ(例えば、float)に暗黙的に変換することができます。あなたの第二のループは、static_castを使用する必要があります。

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

私たちは、明示的に狭い型への変換を行うようにコンパイラに指示するstatic_castを使用しています。キャストを使用しない場合、コンパイラは変換によってデータが失われる可能性があることを警告します。キャスト演算子の存在は、データの精度を失う可能性があることを理解していることを意味します。これはではなく、で、適切な場所はreinterpret_castです。 static_castを使用すると、少なくともコンバージョンを制限することができます(たとえば、Bird*Nuclear_Submarine*に変換することはできません)。 reinterpret_castにはこのような制限はありません。

また、この件についてはBjarne Stroustrupとします。

9

私は最善の方法は、関数オブジェクトを使用することであると思う:

続い
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); } 
}; 

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>()); 

それは英語で行われているものを言いますので、これは最も読みやすいです:変換シーケンスを静的キャスティングを使用して別のタイプに変換します。そして将来のキャストは1行で行うことができます。

1

キャストは自動的なので、明示的にする必要はありません。
しかし、あなたは標準的なアルゴリズムを使用することができます

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

は、情報の潜在的な損失があるcharにフロートから戻って変換を。だからあなたはもっと明白にする必要があります。

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

ここでは、浮動小数点数をとり、charを返すoperator()を持つMyTransformクラスを使用します。それは援助するのが簡単なはずです。

0

これは誰も言及していませんが、浮動小数点で何らかの算術演算を行っている場合は、切り捨てる代わりに丸めたいかもしれません。もしchar 49を持っていれば、4.9E1それは4.89999999E1に変わるかもしれません。それは、それをcharに戻すと48になります。

浮動小数点で何もしていない場合、これは問題ではありませんが、なぜ浮動小数点として最初に必要なのですか?

関連する問題