この投稿では、浮動小数点と固定小数点について説明します。
浮動小数点
IEEE754の32bit浮動小数点(単精度)は、符号1bit、指数8bit、仮数23bitで表現します。
例)10進数 85.125
浮動小数点 0x42AA4000
ここでは変換方法の説明は省きますが、変換には多くの処理が必要です。
固定小数点
固定小数点は、各企業でルールを決めて使っていると思います。ここでは32bit固定小数点を符号1bit、整数15bit、小数点16bit(1/65536)で表現することにします。
例)10進数 85.125
固定小数点 85.125×65536 = 0x00552000
FPU (Floating Point Unit)
FPUは、MCUのCoreに搭載されているUnitです。プログラムで浮動小数点の宣言(float)するとFPUの搭載MCUと非搭載MCUでは次のような違いがあります。
FPU | 処理スピード | コード量 | 価格 |
---|---|---|---|
搭載MCU(FPU命令コードあり) | 早い | 少ない | 高い |
非搭載MCU(FPU命令コードなし) | 遅い | 多い | 安い |
その為、FPU非搭載MCUで固定小数点を用いて場合があります。
浮動小数点と固定少数点の違い
浮動小数点と固定小数点では次のような違いがあります。
小数点 | 規格 | 計算 | 表現できる範囲 | 計算精度 |
---|---|---|---|---|
浮動小数点 | 規格がある | 難しい | 広い | 高い |
固定小数点 | 各企業で異なる | 簡単 | 狭い | 低い |
FPU搭載MCUを使っていても古いレガシーコードが残っていると固定小数点のコードが残っていることがあるので、ご注意ください。
浮動小数点の注意
浮動小数点は、次のような結果となるので比較する際は、注意してください。
float f = 0.1f * 10U; /* f = 0.99999994f となります */
if( f == 1.0f )
{
/* 期待通りにならない場合があります */
}
例えば、0.0fとの比較であれば次のようなコードを用いる場合があります。
#define iEPSILON 1e-6f /* 誤差 */
#define omABS_F(val) ( (val) < 0.0f ) ? -val ) /* 絶対値 */
#define omFLOAT_ZERO(val) ( omABS_F(val) < iEPSILON ) ? 0.0F /* 誤差範囲まで0.0fとした比較 */