開発言語には、それぞれ癖があり、また、バグもあります。それら言語を使用する開発者側が、それらを理解しプログラミングを行わないと言語によるバグを実装してしまう事さえあります。
プログラミングの仕事を行っていると時々、思う通りに動かず調べていくと言語自身のバグに到達する事があります。
仕事は、当然、直ぐにこなさなければならないので、言語のアップデートやパッチ、バージョンアップなど待っていられません。
その場合、プログラマが工夫して別の方法でプログラミングするしかありません。
PHPも例外なく、癖があります。
コンピュータの世界には、浮動小数点と言う考え方があります。
みなさんExcelを使用されていて、時々、計算結果が「-1E-09」の様な書式の値になってしまった事があると思います。
プログラミング等のIT系の仕事に携わった事がないと何を意味している記号なのか分らないと思います。
ちなみに、この記号は、以下を表しています。
-1E-09 = -0.000000001
試にExcelに「-0.000000001」を入力して、その入力した列の幅を狭めて頂くと「-1E-09」と表示されると思います。
これが最も、みなさんに身近な浮動小数点だと思います。
「-1E-09」は何を意味しているのか解説しますと、
「-1」は、そのまま、-1の事です。これを仮数と言います。
「E-09」は、10の-9乗を意味しています。これを指数と言います。
「-1E-09」は、-1 × 10の-9乗の事。つまり、「-0.000000001」の事です。
先程、Excelで入力した「-0.000000001」の小数点の下に「0」を3つ追加してみて下さい。すると「-1E-12」となったと思います。
また、「0」を3つ追加してみると「-1E-15」となります。これは、桁の限界まで変わらず10の-x乗のxが増えていきます。
例えば、「-0.000000000000000000001」をコンピュータに記憶させると少なくとも24文字分のメモリが必要になります。対して、-1E-21であれば、6文字分のメモリで済むわけです。実際のコンピュータ内での値を文字で保持してはいませんが、考え方はこんな感じです。
PHPは、この部分に癖があります。
0.1と0.7を足し算し10倍して小数点を切り捨てる計算をしてみます。
それをPHPでプログラムすると以下の様な形になります。
floor((0.1+0.7)*10)
「*」は、掛け算の「×」の意味です。
floorは、小数点を切り捨てる関数です。
答えは、当然、「8」になるとお考えでしょうが、PHPの場合は「7」になってしまいます。
PHPのマニュアルにも乗っているのですが、浮動小数点での弊害です。
実際に0.1に0.7を足し算し10倍した段階で、PHPは、「7.9999999999999991118...」と保持しています。それを小数点以下を切り捨てると、「7」になってしまう事は理解できると思います。
PHPは、この部分に癖があります。
当然ですが、この現象を知らずにPHPでプログラムを組んでしまうと小数の計算で間違いを引き起こします。
ネットで調べれば直ぐに検索できる内容ですが、問題が発生するまで知らない技術者が多くいます。
実際に当社で面接した中で、この現象を知っている技術者は少なかったです。