俺の報告

RoomClipを運営するエンジニアの日報(多分)です。

日報 #67 - ボケっとしてるとハマる罠

続けることに意味があるんです→意味なんてないけど続けるんです!
となるのにさほど時間はいらなかったようだな。
今日だってとにかく日報だ。

さて本日は「うわ懐かしいミスしたなぁ」という話(雑談)をして、 さっさと終わろうかと思います。
プログラマにとっては至極基本的な話で、 PC嫌いの人達が「なんだよ、コンピュータってそんなこともできねぇのかよ!」と鬼の首をとったかのうような気持ちになれるお話です。

IEEE 754、浮動小数点周りの標準規格に基づく、よくある間違いの話です。
今日ボクがやってしまったミスをとても簡単に表すとこんな感じです。

$a = 0.1;
$b = 1 - 0.9;

if ($a === $b)
  echo ’TRUE’;
else
  echo ‘FALSE’;

あぁーッて感じですね。
$aと$bともに0.1なのだから、これはTRUEだ!というボンミスでございます。
これはもちろんそうなりません。
詳しくはここ参照(http://php.net/manual/ja/language.types.float.php)ですが、
早い話が、0.1なんていう数字は2進数じゃ表現できないんですね。
0.9も表現できません。
なので、$aも$bも、内部数値はびみょーーーに異なります。
abs($a - $b)を吐かせれば2.7755575615629E-17こんな数値が出てきます。
しゃーなしですね。
小数点を含む計算を行う時は、基本的に任意精度数学関数をちゃんと使いましょう、という話でした。