いくつかのラジアン角度をバイナリ ファイルに書き込みたいと考えています。そうしている間にスペースを節約する方法はありますか?
私はそれらを度に変換してショートとして書き出すことを検討しましたが、ショートに変換すると小数部分が失われるため、うまくいきませんでした...
何か案は?
編集:小数点以下2桁または3桁の精度が必要です
範囲と精度です。そして、あなたはどちらについても十分な情報を提供していません。
そこで、いくつかの合理的な (希望する) 仮定を立てます。
すべての値が 0 から 2π (0 から 360°) の範囲にあると仮定します。
このような値を 32-bit として保存する場合float
、符号 (常に負でない数値) に 1 ビット、指数 (非常に大きくなることはありません) に 8 ビット、仮数に 23 ビットを使用しています。 (これはおそらく必要以上の精度です)。64 ビットを使用している場合double
は、明らかにさらに多くのスペースを使用しています。
1
最も明白な解決策は、値がラジアンの一部を表すように固定小数点表現を使用して、小さな符号なし型を使用することです (負の値は必要ないため) 。0 から 2π (0 から約 6.28) の値の場合、 10 進数の 2進小数点の前に 3 ビットが必要です。あとは、必要な小数部のビット数を決定する必要があります。
8 ビットの符号なしの型 (通常はunsigned char
) を使用すると、2 進小数点の後に 5 ビットが与えられるため、値 1 は 2 -5ラジアン (約 1.82°) を表します。これは、あなたが必要としている「小数点以下 2 桁または 3 桁の精度」を得るにはかろうじて十分ですが、実際には必要以上に粗いのではないかと思います。
16 ビットの符号なし型 (通常はunsigned short
) を使用すると、2 進小数点の後に 13 ビットが与えられるため、値 1 は 2 -13ラジアンを表します。これは約 0.007°、つまり約 25 秒角です。これは目的には十分な精度である可能性があり、通常は の半分のストレージですfloat
。
これはすべて、値を 32 ビットfloat
の s として格納するだけでは不十分であることを前提としています。最近はディスク容量が安くなり、さらに安くなりつつあります。
異なるシステム間でデータを共有したい場合、バイナリ値をファイルに保存すると問題が発生する可能性があることにも注意してください。特にバイト順は問題になる可能性があります。バイトのストリームであるフォーマットを定義できる場合 (たとえば、16 ビットの符号なしの値を表すバイトのペアで、最上位バイトが最初になる - それが「ネットワーク バイト オーダー」)、その問題を軽減できます。整数値は、浮動小数点よりも扱いが簡単です。
どのくらいの精度/分解能が必要ですか?
半円の精度/解像度で処理できる場合、値ごとに 1 ビットで十分です。つまり、1 バイトに 8 つの値を収めることができます。
...
圧縮?
実装には少しコストがかかる可能性がありますが、ぎっしり詰まったバイナリ データよりもスペースが少なくて済む場合があります。さらに、圧縮されていない形式は、人間が読める ASCII など、ほとんど何でもかまいません。
次のようなバイトとしてそれらを書き出す Quake ソース コードのメソッドがあります。
((int)radian*256/360) & 255 //radian is the angle
次に、次のように読み取ります。
b * (360.0f/256) //b is the byte read in
私がテストしたところ、小数点以下約2桁の精度が残っていますが、これで問題ありません。