バイナリファイルの印刷と望ましい精度
-
24-09-2019 - |
質問
私は、プロットのためにMatlabまたはGnuplotにインポートできるように、フローティングポイント番号をテキストファイルに含む1-DアレイであるZ1と言う変数を印刷しています。バイナリファイル(.dat)は.txtファイルよりも小さいと聞きました。現在、.txtファイルへの印刷に使用している定義は次のとおりです。
void create_out_file(const char *file_name, const long double *z1, size_t z_size){
FILE *out;
size_t i;
if((out = _fsopen(file_name, "w+", _SH_DENYWR)) == NULL){
fprintf(stderr, "***> Open error on output file %s", file_name);
exit(-1);
}
for(i = 0; i < z_size; i++)
fprintf(out, "%.16Le\n", z1[i]);
fclose(out);
}
私には3つの質問があります:
バイナリファイルはテキストファイルよりも本当にコンパクトですか?;
はいの場合、上記のコードを変更する方法を知り、配列Z1の値をバイナリファイルに印刷できるようにしたいと思います。 fprintfをfwriteに置き換える必要があることを読みました。私の出力ファイルは、dodo.datには、行ごとに1つの浮動数を持つ配列Z1の値を含める必要があると言います。
コードには%.16leがありますが、長いダブルの15精度の数字があるため、%.15leは正しいと思います。これにより、任意のフィールドへの拡張が希望の数を保持することができると考えているため、ドット(。)を幅の位置に入れました。私は正しいですか? %.16LEの例として、16の精度桁を提供する1.0047914240730432E-002のような出力を持つことができます。幅の代わりにドット(。)を幅の位置に配置するのは良い練習ですか?
どうもありがとう...
アップデート に変わります:
for(i = 0; i < z_size; i++)
fwrite(&z1, sizeof(long double), 1, out);
「WB+」への変更に加えてOK? Matlabのバイナリファイルを読むことができません。
解決
はい、バイナリファイルはよりコンパクトですが、あなたは移植性を失い、他のさまざまな潜在的な問題も失います。したがって、データファイルが問題に大きくなったり、エクスポート/インポートが遅い場合を除き、可能であればテキストに固執することをお勧めします(たとえばzipを使用して、常にそれらを保管するためにそれらを圧縮できます)
「W」の代わりに「WB」でファイルを開き、使用します
fwrite()
- ファイルに「行」がなくなっていません - それは単に(バイナリ)浮動小数点値のストリームになりますあなたは間に混乱しているかもしれません
double
とlong double
- along double
サイズが最大16バイトで、最大約32桁の精度があります(ただし、これは実装依存です - 長いダブルは一般に10、12、または16バイトです)。 adouble
通常、8バイトで、約16桁の精度があります。
Matlabは対処できない場合があります long double
(それは十分に標準化されていないので)ので、あなたはおそらくあなたのデータファイルにダブルを書きたいだけです、例:
for (i = 0; i < z_size; i++)
{
double z = (double)z1[i];
fwrite(&z, sizeof(double), 1, out);
}