十六進数と浮動小数点数
浮動小数点数(ふどうしょうすうてんすう、英: floating point number)は、
浮動小数点方式による数のことで、もっぱらコンピュータの数値表現において、
それぞれ固定長の仮数部と指数部を持つ、数値の表現法により表現された数である。(Wiki)
前書き、導入などすっ飛ばしていきなり説明していきます。
また、ここから十六進数と浮動小数点数(今回はFloat型を扱う)という存在について知っているという前提で話をしていきます。
自分は良くゲーム解析などをやっているのですが浮動小数点数について知っていると解析の手助けになることが多いです(n64以降のゲーム)
パソコンに携わるのであれば知っておいて損はないので是非知っておきましょう。
浮動小数点数は符号部、指数部、仮数部の三つから構成されています
– 符号部は1ビットで正負を示します
– 指数部は8ビットで 0 から 255 の値をとります
– 仮数部は23ビットです。
これで1.xxxxxxxxのような先頭が1の二進数の小数点を表現します・
まず二進数での少数の表し方としては
0.5 = 2^(-1) = 0.1
0.25 = 2^(-2) = 0.01
0.125 = 2^(-3) = 0.0001
0.75 = 0.5 + 0.25 = 2^(-1) + 2^(-2) = 0.11
みたいな感じです(ここは知ってる前提でいきます)
そして仮数は1.1(2進数) = 1.5 のように一の位が1の小数になります。
これは正規化とかの意味がありますがそんなに気にする必要はないです。
解析では4Byteの数字から少数に直す方が大事なので今回はそっちのみ書きます
まずはこいつを見てくれ、こいつをどう思う?
すごく・・・興味深いです・・・(少数派)
これはとあるゲームのとあるメモリなのですが
聡明な読者諸君はこれを見た瞬間気になるところがいくつかでてくると思います。
とりあえず例を挙げると
1. 45から始まるものが多い
2. 0x3C23D70Aが三連続のところがある
3. 80から始まるメモリ
とりあえず1と3は今回は無関係なのでとばして2について話します
まず「0x3C23D70A」という数、
これを仮にFloat型と仮定して変換した場合
「0.01」という十進での小数点が出てきます。
具体的に見ていきましょう!
まず0x3C23D70Aを2進数に変換すると
0011 1100 0010 0011 1101 0111 0000 1010
という32bitの数列が得られます。
ここで「符号部は1ビットで正負を示します」
0011 1100 0010 0011 1101 0111 0000 1010
今回先頭bitは「0」です、
つまり今回は正の数(プラスの数)というわけです。
次に指数、「指数部は8ビットで 0 から 255 の値をとります」
0011 1100 0010 0011 1101 0111 0000 1010
今回指数部は「011 1100 0」十進法にすると「120」です。
更にその次「仮数部は23ビットです」
0011 1100 0010 0011 1101 0111 0000 1010
仮数は少しややこしいです、その原因として「最初のビットは常に1となるので書かない」という決まりがあるからです。
具体例をみましょう、ここに「10.01(2進数)」という数字があるとします、
当然最初の数字は1ですね(わざわざ010.01みたいに書く必要がない)
そうと分かればこの1bitは省略可能、つまり1bitだけ精度が上がるということです。
なので今回の「010 0011 1101 0111 0000 1010」を翻訳すると
「1.0100 0111 1010 1110 0001 010」
十進法で「1.28」となるわけです。
ここまでで、
– 符号部 :0
– 指数部 :1111000[120]
– 仮数部 :1.0100011110101110000101[1.28]
となることを説明しました、あとはこの3つの数字をどう使うかです。
これは数式で表すと[A:符号部,B:指数部,C:仮数部]
FLOAT型 =
(-1)^A * 2^(B – 127) * C
で表せます。(文字で書くと面倒なので数式で妥協)
今回なら[A=0,B=120,C=1.28]なので
(-1)^0 * 2^(120 – 127) * 1.28
= 1 * 2^(-7) * 1.28
= 0.0078125 * 1.28
= 0.01
となります、割と簡単ですね.
というわけで浮動小数点数と十六進数の話しはここで終わりなのですが少し解析のお話しをします。
先ほどの画像で0x3C23D70Aが三連続のところがありましたね、今ではこれが「0.01」が3つ連続していると考えることが出来ます。
だからなんだという話ですがこれは極めて重要です。
結論から言うとこれは今尚根強いファンが存在する神ゲー「ゼルダの伝説時のオカリナ」の一部のメモリです。
3Dゲーム…… 浮動小数点数3連続……
閃いた!!!
これはオブジェクトのXYZサイズを表しているんですね(天啓)
Unityなどでは「Vector3」などの形があるのでなんとなくわかるでしょう(時オカではXYZ方向へのサイズはそれぞれ独立している)、
ちなみに他に「座標、速度」などが考えられますが座標の場合全て一致するのは凄く稀、
速度なら止まっている場合は全て「0」、少なくとも滞空していない限りY速度は「0」なのでその辺から判断可能です。
サイズや座標の特定なら別にこんな知識必要無いですが話したかったので無理矢理こじつけました、本当はもっとスマートに行けます。
*画像には座標、速度も載っています。興味があれば考えてみてください。
あとがき
「部長がブログを書いたら自分も書く」
自分は過去にこんな軽率な発言をしてしまいました、これは
「どうせ部長は何もしないだろう」そんな予想に基づき発した言葉です。
しかし予想を裏切り部長は書きました、
それからというもの高頻度でブログの取り立て、オンライン部会で晒上げなどの行為が絶対正義の名の下にと行われてきました。
厳しくないサークルとは一体何のことだったのか? 閉口する次第です。
それでも数ヶ月間は堪え難きを堪え、忍び難きを忍び寡筆の姿勢を崩しませんでした。
理由は単純に怠けていた……
からでは無く前回の記事で書いたように書くことがなかったからです。
書くことがないなら仕方ない、もういっそのこと電算の告発文でも書いてしまおうかと思っている中事態は風雲急を告げました。
新入生が入ってきました、それも結構な数が!
コロナの影響で新歓などが出来ず長い長い電算の歴史はもう終わりと決めつけていたので非常に嬉しかったです。
新入生がブログリレーなどで早速記事を書き始めている中このままだんまりを決め込むのは先輩として…というか人として非常にまずい、そんな結論に至り筆をとることになりました。
ここで先輩としての面子を保つためには「知的」かつ「電算っぽい」記事が要求されます。
そんな悪条件のもと無理やりひり出したのが本ブログです、なので多少のガバは許して下さい。
そして今回でブログのネタをひとつ消費したのでスタックが空になりました、これ以上は例外を投げることになります。
正直1つだけやろうと思っていたことがあるのですがそれに近しい事をやった猛者が部会の議題に挙げられ処刑、全ての記事が検閲に遭い焚書されました。
企業などが見る可能性があるので仕方ないですが残念です、今は彼の復活を祈るばかりです。
あとこれは仕方のないことですがコメントが減りました、前までは部員のコメントがあったので多少活気がありましたが今はもう限界集落のそれです。
ところで電算には「オンラインカタン」という問題児がいます。
何故カタンを選出したのか?そういったセンスも疑問ですが真の謎は完成予定です。
完成予定が何度も引き延ばされその度自分は呆れ返ります、当の本人は悪びれた様子もなく「サクラダファミリア」とネタにする始末。
もうすぐ完成という噂を耳にしますが一体何がどうなってるんでしょうね?
まあ上に挙げたゲームも1996年発売予定で1998年11月21日に発売しました、延期されるゲームでも神ゲーは多いのでカタンにはその分期待が集まりますね。
次の投稿は「オンラインカタン」が完成したら書くかもしれません(未定)。
痛みに耐えて、よく頑張った。感動した!