プチコン3号の実数型をバイナリデータに変換する

  • tags
    • petitcom
  • last modified2015-02-23
  • created2015-02-07

概要

プチコン3号で倍精度浮動小数点数を頑張ってバイナリデータに変換する.

そもそも実数型を基準にすれば変換いらないんじゃないかという事に作ってから気づいたけれど, 通信では文字列or整数しか送れないようなので使い道は無いこともないみたい.

一応テストした範囲(10万回くらい乱数食わせた)では変換によって数値が変わらないことは確認したけれど,駄目なケースあるかもしれない. inf/NaNは対応している.

リスト

' 実数を32bit整数2つに変換
DEF PACK_FLOAT F OUT R1,R2
 VAR E%,F#,T#,T%
 R1=0
 IF F==0 THEN R2=0:RETURN
 IF F!=F THEN R2=&H7FF80000:RETURN
 R2=(F#<0)<<31:F#=ABS(F)
 T#=F#-F#
 IF T#!=T# THEN R2=R2 OR &H7FF00000:RETURN
 E%=FLOOR(LOG(F#,2))
 F#=F#*POW(2,20-E%)
 T%=FLOOR(F#)
 R2=T% AND &HFFFFF OR R2
 F#=(F#-T%)*4294967296
 IF F#>=2147483648 THEN
  R1=F#-4294967296
 ELSE
  R1=F#
 ENDIF
 R2=R2 OR (E%+1023<<20)
END

' 32bit整数2つから実数に変換
DEF UNPACK_FLOAT R1,R2 OUT F
 VAR R1%=R1,R2%=R2
 VAR E%=(R2% AND &H7FF00000)>>20
 IF E%==2047 THEN ' inf/NaN
  VAR I#=POW(2,1024)
  IF (R2% AND &HFFFFF) || R1% THEN
   F=I#-I#
  ELSE
   IF R2%<0 THEN F=-I# ELSE F=I#
  ENDIF
  RETURN
 ENDIF
 F=0#:IF R1%==0 && R2%==0 THEN RETURN
 F=R1%:IF R1%<0 THEN F=F+4294967296
 F=F+((R2% AND &HFFFFF) OR &H100000)*4294967296
 F=F*POW(2,E%-1075)
 IF R2%<0 THEN F=-F
END