IEEE754 単精度浮動小数点数の形式:binary32 の変換

 C言語の実数floatは、メモリの中では32ビットの領域を使います。

  • 符号ビット: 1ビット
  • 指数部の幅: 8ビット
  • 仮数部の幅: 23ビット

 32ビット=4バイトのデータは、たとえば、16進で表現すると、

  41 c8 00 00

は、実数の25.0です。プログラムで外部とのやり取りで実数を扱えないとき、ASCIIコードだけでデータを送ったり受けることができます。

  Modbusの利用 (6) 電力計SDM120M

メモリの内容を読み出す

 共用体unionは、同じメモリ領域に複数の変数を定義できます。Arduino IDE 1.8.13 ESP32で実行しました。

 a.x = 3.141592;は実数です。そこを整数型で8桁表示させると、メモリの内容が読み出せます。

  union { float x; int i; } a;
  
  a.x = 3.141592;
  int i;

  printf("x= %f \n", a.x);
  printf("IEEE 754 binary32内部形式は 0x%08x \n", a.i); 
  printf("xのアドレスは 0x%x \n", (unsigned int)&a.x); 


 実行結果です。

x= 3.141592
IEEE 754 binary32内部形式は 0x40490fd8
xのアドレスは 0x3ffb1f8c

 別の方法です。

 実数piのポインタ&piを4バイトのint型でキャストをし、そこが指している内容を読み出します。

    float pi = -3.141592;
    Serial.print("元のデータ ");Serial.println(pi,6);
    uint32_t ii = *((uint32_t*)&pi);
    Serial.print("IEEE 754 binary32内部形式は ");Serial.println(ii,HEX);



戻す

 符号、仮数、指数をそれぞれ分離し、最後に全部かけて、小数点6桁を表示します。

(2021/11/25 修正)

int8_t f = pow(-1, int(bitRead(ii,31)));
double  k = 1 + (double)((((ii<<1)<<8)>>9))/pow(2,23); 
float s = (float)pow(2,(int8_t)((uint8_t)((ii<<1)>>24)-127));
Serial.print("内部形式を実数に戻した ");Serial.println(f*k*s,6);


 実行結果です。

元のデータ -3.141592
IEEE 754 binary32内部形式は C0490FD8
内部形式を実数に戻した -3.141592

確認

 Floating Point to Hex Converterのサイトに行って確認します。

python

 pythonではstruct.packを使う4桁のバイト列が得られます。

  初めてのRaspberry Pi BLEプログラミング (5) BME280②温度、気圧、湿度

 struct.unpackを使うとと簡単に元の実数へ戻せます。

  センサ・シリーズ 温湿度①SHT31 その5 BLEセントラル

(参考にしたURL)浮動小数点数の内部表現を取得してみよう

前へ

超精密温度計の製作⑤7セグLEDに表示

次へ

フルカラー7セグメントLEDの点灯①接続