hinekure.net が http://hspdev-wiki.net/ から自動クローリングした結果を表示しています。画像やリソースなどのリンクが切れています。予めご了承ください。
浮動小数点 - HSP開発wiki
トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS

小ワザ

浮動小数点

浮動小数点とは

浮動小数点のビット構成

HSPのdouble型は64bitの倍長精度浮動小数点です。一般的な倍長精度浮動小数点のビット構造はつぎのようになっている。

double(64bits)
部分名称符号部指数部仮数部
ビット列1ビット11ビット52ビット

指数部は正と負の両方を扱えるようにするために1023を足す(ゲタ)。

仮数部の整数部は1以上2未満の値になるようにする。(正規化)。

仮数部は-1して0未満とする。(正規化では1〜2未満?)

モジュールファイル

とりあえず浮動小数点のビット列表示を作りました。 計算で求める方法は自分には分からないのでメモリをそのまま参照してます。

filev3try_bitdispf.hsp
Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
    ;
    ; for HSP 3.0a
    ;                                                         kz3
 
    #module
    ; 倍長精度浮動小数点のビット列を表示する(peek版)
    ;------------------------------------------------------------
    #deffunc bitdispf var d
        s = ""
        repeat 8
            byte = peek(d, cnt)
            repeat 8
                if byte & (1<<cnt) : s="1"+s : else : s="0"+s
            loop
            s=" "+s
        loop
 
        mes s
        return
    #global

2.5のビット列を手動計算

まず2.5を仮数部と指数部で表現すると

10.1 = 10.1 * 10@@@0@@@ (2進)
2.5 = 2.5 * 2@@@0@@@ (%10.1 = %10 + %1 / %10 = 2 + 1 / 2 = 2.5)

仮数部が1〜2未満ではないので仮数部を右に1ビットシフトさせて正規化する。

10.1 * 10@@@0@@@ = 1.01 * 10@@@1@@@ (2進)
2.5 * 2@@@0@@@ = 1.25 * 2@@@1@@@ (%1.01 = %1 + %1 / %100 = 1 + 1 / 4 = 1.25)

仮数部が0未満ではないが-1するので

0.01 * 10@@@1@@@(2進)
0.25 * 2@@@1@@@ (%0.01 = %1 / %100 = 1 / 4 = 0.25)

指数部には1023を足すので

0.01 * 10@@@100 0000 0000@@@(2進)
0.25 * 2@@@1024@@@

よって

ビット列
符号部00
指数部10241000000 0000
仮数部1.25(0.)0100 00000000 00000000 00000000 00000000 00000000 00000000
全体2.50100000 00000100 00000000 00000000 00000000 00000000 00000000 00000000

2.55のビット列を手動計算

まず2.55を仮数部と指数部で表現すると

2.55 = 2.55 * 2@@@0@@@

仮数部が1〜2未満ではないので仮数部を右に1ビットシフトさせて正規化する。

2.55 * 2@@@0@@@ = 1.275 * 2@@@1@@@

仮数部が0未満ではないが-1するので

0.275 * 2@@@1@@@

指数部には1023を足すので

0.275 * 2@@@1024@@@

つぎに仮数部を求める。

0.275 < 0.5(2@@@-1@@@) ・・・ NG

0.275 - 0.25(2@@@-2@@@) = 0.025
0.025 - 0.015625(2@@@-6@@@) = 0.009375
0.00937 - 0.0078125(2@@@-7@@@) = 0.0015625
0.0015625 - 0.0009765625(2@@@-10@@@) = 0.0005859375
0.0005859375 - 0.00048828125(2@@@-11@@@) = 0.00009765625
0.00009765625 - 0.00006103515625(2@@@-14@@@) = 0.00003662109375
0.00003662109375 - 0.000030517578125(2@@@-15@@@) = 0.000006103515625
0.000006103515625 - 0.000003814697265625(2@@@-18@@@) = 0.000002288818359375
0.000002288818359375 - 0.0000019073486328125(2@@@-19@@@) = 0.0000003814697265625
0.0000003814697265625 - 0.0000002384185791015625(2@@@-22@@@) = 0.0000001430511474609375

0.0000001430511474609375 -
0.00000011920928955078125(2@@@-23@@@) = 0.00000002384185791015625

0.00000002384185791015625 -
0.00000001490116119384765625(2@@@-26@@@) = 0.00000000894069671630859375

0.00000000894069671630859375 -
0.000000007450580596923828125(2@@@-27@@@) = 0.000000001490116119384765625

0.000000001490116119384765625 -
0.000000000931322574615478515625(2@@@-30@@@) = 0.000000000558793544769287109375

0.000000000558793544769287109375 -
0.0000000004656612873077392578125(2@@@-31@@@) = 0.0000000000931322574615478515625

0.0000000000931322574615478515625 -
0.0000000000582076609134674072265625(2@@@-34@@@) = 0.0000000000349245965480804443359375

0.0000000000349245965480804443359375 -
0.00000000002910383045673370361328125(2@@@-35@@@) = 0.00000000000582076609134674072265625

0.00000000000582076609134674072265625 -
0.00000000000363797880709171295166015625(2@@@-38@@@) =
0.00000000000218278728425502777099609375

0.00000000000218278728425502777099609375 -
0.000000000001818989403545856475830078125(2@@@-39@@@) =
0.000000000000363797880709171295166015625

0.000000000000363797880709171295166015625 -
0.000000000000227373675443232059478759765625(2@@@-42@@@) =
0.000000000000136424205265939235687255859375

0.000000000000136424205265939235687255859375 -
0.0000000000001136868377216160297393798828125(2@@@-43@@@) =
0.0000000000000227373675443232059478759765625

0.0000000000000227373675443232059478759765625 -
0.0000000000000142108547152020037174224853515625(2@@@-46@@@) =
0.0000000000000085265128291212022304534912109375

0.0000000000000085265128291212022304534912109375 -
0.00000000000000710542735760110185871124267578125(2@@@-47@@@) =
0.00000000000000142108547152010037174224853515625

0.00000000000000142108547152010037174224853515625 -
0.00000000000000088817841970012523233890533447265625(2@@@-50@@@) =
0.00000000000000053290705181997513940334320068359375

0.00000000000000053290705181997513940334320068359375 -
0.000000000000000444089209850062616169452667236328625(2@@@-51@@@) =
0.000000000000000088817841969912523233890533447265125

0.0000000000000002220446049250313080847263336181643125(2@@@-52@@@)
0.000000000000000088817841969912523233890533447265125 < 2@@@-52@@@ ・・・ NG

仮数部は52ビットなのでこれ以上演算はできないので打ち切る。

以上により

ビット列
符号部00
指数部10241000000 0000
仮数部1.275(0.)0100 01100110 01100110 01100110 01100110 01100110 01100110
全体2.550100000 00000100 01100110 01100110 01100110 01100110 01100110 01100110

255.000000のビット列を手動計算

まず255.000000を仮数部と指数部で表現すると

255.000000 = 255.000000 * 2@@@0@@@

仮数部が1〜2未満ではないので仮数部を右に1ビットシフトさせて正規化する。

255.000000 * 2@@@0@@@ = 127.5 * 2@@@1@@@

仮数部が1〜2未満ではないので仮数部を右に1ビットシフトさせて正規化する。

127.5 * 2@@@1@@@ = 63.75 * 2@@@2@@@

仮数部が1〜2未満ではないので仮数部を右に1ビットシフトさせて正規化する。

63.75 * 2@@@2@@@ = 31.875 * 2@@@3@@@

仮数部が1〜2未満ではないので仮数部を右に1ビットシフトさせて正規化する。

31.875 * 2@@@3@@@ = 15.9375 * 2@@@4@@@

仮数部が1〜2未満ではないので仮数部を右に1ビットシフトさせて正規化する。

15.9375 * 2@@@4@@@ = 7.96875 * 2@@@5@@@

仮数部が1〜2未満ではないので仮数部を右に1ビットシフトさせて正規化する。

7.96875 * 2@@@5@@@ = 3.984375 * 2@@@6@@@

仮数部が1〜2未満ではないので仮数部を右に1ビットシフトさせて正規化する。

3.984375 * 2@@@6@@@ = 1.9921875 * 2@@@7@@@

仮数部が0未満ではないが-1するので

0.9921875 * 2@@@7@@@

指数部には1023を足すので

0.9921875 * 2@@@1030@@@

次に仮数部を求める。(爆;;

int(2.55*100)=254について

  • 循環小数による丸め誤差? -- kz3 2005-10-16 22:59:19 (日)
  • いままで整数値のみのプログラムしか作ってなかったから慌てふためいた。 -- hiroki? 2005-10-17 08:21:39 (月)
  • 僕もです・・・3Dを勉強しているので今後浮動小数点の理解は何かの役にたつかなぁっと・・・。 -- kz3 2005-10-17 08:36:10 (月)
  • なぜint(2.55*100)=254なのか分かったかも・・・ -- kz3 2005-10-17 14:09:11 (月)
      1
      2
      3
      4
      5
      6
      7
      8
      9
    
     
     
     
     
     
     
     
     
     
    
        a = 2.55 : bitdispf a : mes a
     
        memset a, 0, 3, 0
     
        bitdispf a : mes a
     
        memset a, 0, 4, 0
     
        bitdispf a : mes a
    浮動小数点ビット列表示モジュールを使ってこのようなテストコードを書きました。
  • おっといかん。問題なのは255.000000のビット表現だ。 -- kz3 2005-10-17 22:57:58 (月)
    URL B I U SIZE Black Maroon Green Olive Navy Purple Teal Gray Silver Red Lime Yellow Blue Fuchsia Aqua White

モジュール :
単精度実数と倍精度実数の相互変換

 HSP3.0 

float 型の値(単精度実数値、32bit)(のメモリイメージ)と double 型の値(倍精度実数値、64bit)の相互変換を可能にします。 -- naznyark?

コメント

  • 今までビット構成なんか気にしていなかったのにint(2.55*100)=254が気になったので調べています。 -- kz3 2005-10-16 22:54:18 (日)
  • memcpyじゃバリバリ環境依存かも知れない。peekに書き換えようかな。 -- kz3 2005-10-17 08:38:23 (月)
  • ふぅ^^;2.55の浮動小数表現完了。最後の方は本当に手動なので計算間違いがあるかも知れません・・・本当かどうか確かめたい人は間違っていたら直すか教えてください^^; -- kz3 2005-10-17 13:47:28 (月)
  • (こういう性格なんです・・・<アルティメットさんへ) -- kz3 2005-10-17 13:50:34 (月)
  • ビット構成のところの説明や、いろいろな場所で導入されている説明に「なぜその説明を導入するのか」というところまで理解しきれていません。 -- kz3 2005-10-17 14:31:37 (月)
  • 僕の堅い頭ではお手上げです。 ...逃げ腰 -- hiroki? 2005-10-18 08:39:39 (火)


添付ファイル:
filev3try_bitdispf_b.hsp
373件 [詳細]
filev3try_bitdispf.hsp
451件 [詳細]
filemod_dbl2sng.hsp
255件 [詳細]
トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS
Last-modified: 2008-06-14 (土) 01:50:06 (2003d)