検索
連載

浮動小数点数を固定小数点数に変換するには?Q&Aで学ぶマイコン講座(98)(2/2 ページ)

マイコンユーザーのさまざまな疑問に対し、マイコンメーカーのエンジニアがお答えしていく本連載。今回は、初心〜中級者の方からよく質問される「浮動小数点数を固定小数点数に変換するには?」についてです。

Share
Tweet
LINE
Hatena
前のページへ |       

 C言語プログラムをコンパイルして、浮動小数点数から固定小数点数に変換するVCVT命令をコンパイラに出力させるのは、かなりハードルが高いです。そのため、下記のSTM32CubeIDE V1.16.0(arm-none-eabi-gcc-12.3.1)の例のように、C言語のヘッダファイルで関数のインタフェースを宣言して、変換用関数をアセンブラで実装するのが確実で、時間も節約できます。

 下記は、FPUレジスタS0を、1)関数の引数、2)FPUへの入力用レジスタ、3)FPUからの出力用レジスタとして利用し、汎用レジスタR0を関数からの戻り値として利用することで、VCVT命令で浮動小数点数(float型)から小数部分が2ビットの固定小数点数(int16_t)に変換する関数の一例です。

[ヘッダファイル: fxp2.h]
/* fxp2.h */
#ifndef __FXP2_H__
#define __FXP2_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include <stdint.h>
int16_t fxp2(float x);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
[関数定義: fxp2.s]
.global fxp2
    .section .text.fxp2, "ax", %progbits
    .align 4
fxp2:
    VCVT.S16.F32 S0, S0, #2
    VMOV          R0, S0
    BX            LR

VCVT命令を使わずソフトウェア処理のみで変換する場合

 VCVT命令を使わずにソフトウェア処理のみで変換する場合、下記で対応します。

 変換後の固定小数点数の小数部分のビット数の分だけ1を左ビットシフトした値を掛け算して、浮動小数点数値の小数点を丸めて、整数型にキャストします。いま取り扱っている例では、符号有り16ビット長(小数部2ビット)の固定小数点数に変換したいので、1を2ビット左シフトした値(1<<2)=4を掛け算して、int16_tにキャストします。

int16_t fxp2(float x)
{
    return (int16_t)(x * (1 << 2));
}

 図1は、ソフトウェア処理で浮動小数点数1.75を符号有り16ビット長(小数部2ビット)固定小数点数に変換する例の概念図です。

<strong>図1:ソフトウェア処理による変換の概念図</strong>[クリックで拡大]
図1:ソフトウェア処理による変換の概念図[クリックで拡大]

Copyright © ITmedia, Inc. All Rights Reserved.

前のページへ |       
ページトップに戻る