小数の計算をしたい時、
0.00000052 × 0.000000025
= 0.000000000000013
とやると、見にくくてかないませんよね。なので、
( 5.2 × 10^-7 ) × ( 2.5 10^-8 )
= 1.3 × 10^-14
と桁数を数字で表すのが良いやり方で、化学や物理の分野ではおなじみです。
さらに電子機器を扱う場合、2進数を使う必要もあって、やたら0を書きまくるとたちまち回路上の場所がなくなって大変です。それよりは、"1.3"・"10"・"-14"と必要な「数値」のみを簡潔に記す方がいいですね。
これが「浮動小数」と呼ばれる表現形式です。今日では、float型は広義には浮動小数のこと、狭義には浮動小数の表現方法の一つをさす場合があるようです。
狭義のfloat型は単精度とも呼ばれ、2進数で表現されます。
x × 2^y
(ちなみに、このxを仮数、yを指数と言います。)
たとえば、0.4375を表現してみます。
0.4375 = 0.4375 × 2^0
おわり。
・・・・・・・・・・嘘です; とまあ、ただ漫然と書くとこういういい加減な書き方もできてしまうので、約束事をきめます。上の例の 5.2 × 10^-7 では、仮数の中の整数の部分が"1桁"になっています。float型でもこうすることにしましょう。こうすることで、表し方を1通りに決めることができます。(こうして調整することを正規化といいます。)
0.4375 = 0.4375 × 2^0
= 0.875 × 2^-1
= 1.75 × 2^-2
ここで、整数部分が0から1になりました。
10進数であれば1〜9なら"1桁"ですが、2進数では2より上は2桁で書きます。よって、ここで正規化は完了です。
最後に、数字を2進数に変えます。
1.75 = 1 + 0.5 + 0.25 = 1 × 2^0 + 1 × 2^-1 +1 × 2^-2 より
1.75 × 2^-2
→ 1.11 × 10^-10
この数値を記録するのですが、最初に「2進数で表現する」と決まっているので、いちいち書く必要は無いですね。また、2進数で正規化を行うと、仮数の整数部分が必ず"1"になります。これも必ずなることなので省略が可能です。(こうして文字数を節約することをケチ表現と言います。ケチwww)結局、記録するのは ".75(.11)" "-2(-10)" となります。
狭義のfloat型は32bit、つまり0か1かの組み合わせを32個使って表現します。その内訳は、
全体の±で1桁・指数8桁(左詰め)・仮数23桁(左詰め)
となります。ここで、このままだと指数部分に-2などのマイナスの値も入ることになります。それで困るわけではない(と思い)ますが、実際の値に+127(1111111)して補正を入れます。記録するのは1~254ですが、実際には-126~+127を表すわけです。-2だと、+127して125(1111101)です。
・・・8個ビットあったら 2^8 = 256 で0〜255じゃないのぉ?と私も初めは思いましたが、どうやらコンピュータの処理においては、0と255はそれぞれエラーが起きた時などの表示のために開けてあるそうです。いわゆる"魔法の数字"ですね。
0.4375の表現は、"00111110111000000000000000000000"です。16進数だと、0x3EE00000 ってとこですか。
よくmugenで「FVar(x) は7桁以上がアヤしい」と言われるのは、この仮数部分が実際には23個分しかないのが原因です。2^23 = 8388608 を超えて桁が収まりきらなくなると、正規化で左揃えになった後右側の値の小さい方から消えていきます。
また、数の大きさ自体はVar(x)を大きく超える数値を記録可能で、整数では2147483647でせいぜい10桁が限界なのに対し、2^128 = 3.4028・・・× 10^38 と40桁近くの巨大な数値を記録可能です。とはいえ、下30桁くらいまでは足し算引き算とかできませんが。
おまけ
~
[state 903,821 FVar(0)-1領域目]
type=null
trigger1=1
[state 903,822 FVar(0)-2領域目]
type=null
trigger1=1
[state 903,823 FVar(0)-3領域目]
type=changestate
trigger1=1
value=904
persistent=224 ;E0
ignorehitpause=1
[state 903,824 FVar(0)-4領域目]
type=null
trigger1=1
~
[state 904,821 FVar(0)-1領域目]
type=null
trigger1=1
[state 904,822 FVar(0)-2領域目]
type=null
trigger1=1
[state 904,823 FVar(0)-3領域目]
type=null
trigger1=1
[state 904,824 FVar(0)-4領域目]
type=changestate
trigger1=1
value=5150
persistent=62 ;3E
ignorehitpause=1

Null式変数セット。
続きをたたむ