C++Builderの浮動小数点のバイト数と精度を調べてみる
自分用の覚書。
浮動小数点の有効桁数が気になったので調べて表にしてみた。
Subject は C++Builder と書いているけど、Delphi も基本的に同じ。
なお、比較のために Linux gcc の内容も記入している。
結果はこちらの表の通り。
有効桁数は log10(2^2進数桁数) で算出した。
型 | バイト数 | ビット数 | 指数 | 仮数 | 2進数桁数 | 10進数有効桁数 |
float | 4 | 32 | 8 | 23 | 24 | 7 |
double | 8 | 64 | 11 | 52 | 53 | 15 |
long double (Windows 64bit, iOS 32bit, 64bit) | 8 | 64 | 11 | 52 | 53 | 15 |
long double (Windows 32bit) | 10 | 80 | 15 | 64 | 64 | 19 |
long double (Linux 32bit gcc) | 12 | 80 | 15 | 64 | 64 | 19 |
long double (Linux 64bit gcc, macOS) | 16 | 128 | 15 | 113 | 113 | 34 |
long double について、Windows 32bit だけは拡張倍精度であり、その他は基本的に倍精度です。ただし macOS だけは4倍精度です。
このように、プラットフォームごとに long double のデータサイズが大きく異なることに注意が必要です、。
Win32 の long double のバイト数が大きいのは浮動小数点処理に FPU を使うことにあるようです。
これに対して Win64 は SSE を使っていることで FPU 利用時よりもバイト数が小さくなっているそうです。
http://docwiki.embarcadero.com/RADStudio/Berlin/ja/浮動小数点演算について
Linux の long double が32bitで 12バイトなのは……イマイチよくわからないけど、sizeof(long doble)すると12が返ってくるので、12というのはおそらく事実。ただし指数、仮数に関する一次ソースが見当たらなかったので、この情報は Win32 と Linux64bit の比較から推測しています。 いろいろ調べてみると、データサイズとしては12バイトだけど実際には10バイトしか使っていないらしい。10バイトで処理すると遅くなるからでは、と推測している方がいらっしゃる。
浮動小数点演算ではまった話 - bkブログ
melancholic afternoon
自分が描くコードではこの違いが影響するほどの精度で数値を扱うことをしないので平気だけど、状況によっては問題が出ることもあるだろうから、実数を扱うコードを書くときは気をつけたい点かも。