floatを長さ4のバイト配列(char *の配列)に変換する方法は?私はネットワーク上でいくつかのデータ、tcpを送る必要があり、バイト配列としてfloatを送る必要があります。 (私は2桁の10進数の精度を知っているので、クライアント側で100を掛け、サーバで100で割る - 基本的に整数に変換し、次に& 0xff < <操作でバイトを見つける)。しかし、それは醜いものであり、時間の間に精度を失う可能性があります。一連のバイトとしていかなるタイプを読むfloatを長さ4のバイト配列(char *の配列)に変換する方法は?
答えて
は非常に簡単です:
float f = 0.5f;
unsigned char const * p = reinterpret_cast<unsigned char const *>(&f);
for (std::size_t i = 0; i != sizeof(float); ++i)
{
std::printf("The byte #%zu is 0x%02X\n", i, p[i]);
}
執筆フロートへのネットワークストリームから同様に動作し、あなただけがconst
を残したいです。
常に(任意char
型が許容される)バイトのシーケンスとして任意のオブジェクトを再解釈することが許可され、この明示ないエイリアシング違反。任意の型のバイナリ表現はもちろんプラットフォームに依存するので、受信者が同じプラットフォームを持つ場合は、これを直列化にのみ使用してください。
しかし、これはもちろん、ネットワークにバイトを書かなければならない場合は、彼を助けません。 –
@JamesKanze:確かに 'write(fd、p、sizeof(float))'を使うことができます。質問は誰が*読むことができますか:-) –
'write'が正しいとは事実上ありません。しかし、問題はネットワークを介して出力することでした。だから彼が書いているのは、彼が使っているプロトコルが定義しているフォーマットに対応していなければならない。 –
最初に行う必要があるのは、ネットワークプロトコルの フロートのフォーマットを判別することです。 IBMメインフレーム、Oracle Sparcおよび通常の PCはすべて4バイトの浮動小数点数を持っていますが、3種類の異なる フォーマットを持っています。フォーマットを知っていれば、 移植性の要件に応じて、2つの異なる戦略を使用できます。
プロトコルのフォーマットがIEEE(最も頻繁なケース)の場合、 である必要はありません をIEEEされていないマシンへの移植(WindowsおよびほとんどのUnixは、IEEE —ほとんどのメインフレームではないされている)、 あなたは uint32_t
にフロートを変換するタイプpunningを使用することができますし、いずれかを使用して、出力:
std::ostream&
output32BitUInt(std::ostream& dest, uint32_t value)
{
dest.put((value >> 24) & 0xFF);
dest.put((value >> 16) & 0xFF);
dest.put((value >> 8) & 0xFF);
dest.put((value ) & 0xFF);
}
ビッグエンディアン(通常のネットワーク注文)、または:
std::ostream&
output32BitUInt(std::ostream& dest, uint32_t value)
{
dest.put((value ) & 0xFF);
dest.put((value >> 8) & 0xFF);
dest.put((value >> 16) & 0xFF);
dest.put((value >> 24) & 0xFF);
}
(いくつかのプロトコルで使用されます)。 を使用するプロトコルは、プロトコル用に定義された形式に依存します。
float
からuint32_t
に変換するには、 コンパイラを確認する必要があります。 memcpy
を使用するのは、 で完全に保証されている唯一の方法です。浮動小数点演算で reinterpret_cast<uint32_t&>
を使用し、 のほとんどの(すべて?)コンパイラもunion
を使用してサポートするということです。
あなたにもメインフレームに移植する必要があり、またはフォーマット がIEEE以外のものであれば、あなたはフロートから 指数、記号と仮数部を抽出する必要があります、と で出力各ターゲットフォーマット。次のような何かが(IEEEを使用しないメインフレームを 含む)任意のマシン上 出力IEEEビッグエンディアンに動作するはずですし、あなたにいくつかのアイデアを与える必要があります。
oxdrstream&
oxdrstream::operator<<(
float source)
{
BytePutter dest(*this) ;
bool isNeg = source < 0 ;
if (isNeg) {
source = - source ;
}
int exp ;
if (source == 0.0) {
exp = 0 ;
} else {
source = ldexp(frexp(source, &exp), 24) ;
exp += 126 ;
}
uint32_t mant = source ;
dest.put((isNeg ? 0x80 : 0x00) | exp >> 1) ;
dest.put(((exp << 7) & 0x80) | ((mant >> 16) & 0x7F)) ;
dest.put(mant >> 8) ;
dest.put(mant ) ;
return *this ;
}
(BytePutter
は単純なクラスです出力 の定型句を処理し、エラーチェックを行います)もちろん、 の出力がIEEE以外の場合は、出力の操作は異なりますが、これには基本原則が示されています。 (あなたがuint32_t
をサポートしていない多くのエキゾチックなメインフレーム、 の一部への移植が必要な場合は、23ビットよりも大きい任意の 符号なし整数型に置き換えることができます。)
ちょうど1内のデータをオーバーレイエリア、in C
union dataUnion {
float f;
char fBuff[sizeof(float)];
}
// to use:
dataUnion myUnion;
//
myUnion.f = 3.24;
for(int i=0;i<sizeof(float);i++)
fputc(myUnion.fbuff[i],fp); // or what ever stream output....
- 1. 4バイト配列をJavaでfloatに変換する方法
- 2. バイト配列をint配列に変換する方法は?
- 3. バイト配列(char配列)を整数型(short、int、long)に変換する
- 4. char配列のcharをANSI Cの独自のchar配列に変換する
- 5. PNG圧縮バイト配列をBMPバイト配列に変換する
- 6. 文字列配列をfloat配列に変換する
- 7. 変換バイト配列
- 8. NSStringをcharバイト配列に変換する
- 9. phpで4バイト配列を整数に変換するには?
- 10. 配列を含む構造体をバイト配列に変換する方法は?
- 11. 整数値をPythonの4バイトの配列に変換する方法
- 12. 変換のchar配列
- 13. C++変換文字列をバイト配列に変換する方法は?
- 14. C#バイト配列に変換
- 15. 長い配列をバイト配列に変換して別の配列に追加する
- 16. Silverlight 4:bmpバイト配列をpngバイト配列に変換するにはどうすればよいですか?
- 17. バイト配列で表されるInt32配列をC言語でInt32配列に変換する方法
- 18. 数値に可変長のバイト配列
- 19. JNI unsigned charをバイト配列
- 20. char配列を列挙型配列に変換しますか?
- 21. AngularJSは、文字列の配列をfloatの配列に変換します
- 22. バイト配列のExcelファイルをバイト配列のPDFファイルに変換する
- 23. ファンクションキーF3をバイト配列に変換する方法は?
- 24. デリゲートをバイト配列に変換する方法は?
- 25. json配列をflex 4配列(as3)に変換する方法は?
- 26. WinRt AppのWriteableBitmapイメージをバイト配列に変換する方法
- 27. PdfCopyをJavaのバイト配列に変換する方法
- 28. バイト配列を任意の型に変換する方法
- 29. タプルをC++のバイト配列に変換する方法11
- 30. バイト配列のRGBイメージをグレースケールに変換する方法
精度を維持するには8バイトが必要だと思います。 –
@HennoBrandsmaこれは一般的に「ダブル」です。最新のシステムでは、 'float'は4バイトのIEEE-754形式です。 –
クライアント/サーバーを1つの形式(大/小)に制限しない限り、最終的なソリューションでエンディアンアカウンティングをディスカウントしないでください。 – WhozCraig