「計算結果を、色分けされたドットで表示する」ということは、たまにはやることでしょう。
例えば、演算処理速度のベンチマークのためにストレンジアトラクタを描いてみたり、マンデルブロ集合を描いてみたり・・・。
今回、ちょっとした趣味の世界の話で、様々なデータの類似性をマップ表示にして“見える化しよう”という遊びプロジェクトの一環で、ブラウザ上にひたすらドットを打つプログラムを書いていました。
「Javascriptでええやろ」と始めたのですが、数十万のドットを何層も描画するのは、さすがに重い処理でした。
1.浮動小数の計算結果を、parseIntで整数にして、ドットを打つ
もともと対象とするデータ、あるいはその演算が明らかに浮動小数なので、それを整数にしてドットを打ちます。
「整数にするならparseIntやろ」ということで、x座標、y座標のセットを数十万ドット計算し、それを経時変化を示すために何回も繰り返したわけですが、それは時間が掛かって当然という気もします。
2.整数になればいいんでしょ?なら、ビット演算で良くね?
Javascriptでは「ビット演算を行う前に32ビットの整数に変換する」ことになっています。
“そもそもJavascriptの「数値」はどのような扱いなのか?”から調べた方が良さそうですが、それは調べればいくらでも出てくるのでここでは省略します。
大切なのは、「32ビットの整数になってしまう」ということです。
i=238.555;
document.write(i|0);
document.write(~~i);
上記のJavascriptを実行すると、どちらも”238″となります。
ちなみに「|」は各ビットごとのORですし、「~」は1の補数です(だから2回繰り返している)。
これは、快速です。もうparseIntは使えませんな(言い過ぎ)。
3.負数の場合はどうなる?
i=-238.555;
document.write(i|0);
document.write(~~i);
この結果は”-238″となります。
「そうだよね。-238.555の整数部分は-238だよ。」・・・ではありません。
「-238.555の整数部分は、-239」です。
なので、この方法ではガウス記号の用途には使えません。
4.どこまで行ける?
ブラウザ上にドットを打つくらいなら、せいぜい1000くらいまで使えれば良いのですが、「32ビットの整数」という部分を正しく調べておく必要がありそうです。
結論から言えば、「2147483647.9999998」まで使えます。
“使える”というのは、「整数値にする」という用途です。
Javascriptでは、64bitの浮動小数で数値を持っています。
これは、上位から
1bit:正負
11bit:指数(2の◯◯乗)
52bit:仮数
となっています。
絶対値として大きな数と小さな数を可能な限り表現するために、工夫がなされています。
「指数は1023を加えておいて、マイナス乗もそれなりに表せるようにしておく」のと「仮数の1は省略する(必ず1.***で表現して、頭の1を省略することで表現できる桁を増やす)」です。
これを踏まえて、書くと52bitの仮数は「1111111111111111111111111111111111111111111111111111」と1が52個並んだのが一番大きな数になります。
で、これの頭にさらに1をのっけたのが、“正しい仮数”です。
32bitの整数の場合、頭の1bitは正負の符号ですので、31bitが数値を表現しています。上で頭の1は省略していたので、30bit分シフトさせるのが指数部の役割になります。
指数部は1023を加えて表現しますので、30+1023=1053=(10000011101)2です。
以上を並べて、「0|10000011101|1111111111111111111111111111111111111111111111111111」が、「32bitの整数にしたときの最大の値」となる「64bitの浮動小数」です。
これは、10進数では「2147483647.9999998」となります。
つまり、ドットを打ちたいというレベルであれば何の問題もなく使えるということですね。
大きな値を使ったり、丸め誤差を防ぐために小数点の位置をずらしたりするような計算をする人は、バグの原因になるかもしれません。
ロゴスウェア
最新記事 by ロゴスウェア (全て見る)
- Amazon Linux(EC2)と PHPSTORM で Xdebug を行う - 2018年9月26日
- やらないことの合意 - 2018年6月27日
- 卒園アルバムとプロジェクトマネジメント - 2018年3月30日
Comments are closed.