tetsunosukeのnotebook

tetsunosukeのメモです

数値の割り算でハマる

PHPPostgreSQLに投げてfloorを計算させたら結果が違うんですっ!」

とか言われてちょっと何言ってるかわからない状態になった。

どうもこういうことらしい。int(に見えるリテラル)をintで割ったときの挙動の問題のようだ。

PHPの floor(-155/10)の結果

$ php -r "echo floor(-155/10);"
-16

PostgreSQLのfloor(-155/10) の結果

# select floor(-155/10);
 floor 
-------
   -15
(1 row)

おっとっと。


というわけで、floorをかける前の値が何になっているか調べてみる。

PostgreSQLでは

# select -155/10, 1555/10.0, floor(-155/10);
 ?column? |       ?column?       | floor 
----------+----------------------+-------
      -15 | 155.5000000000000000 |   -15
(1 row)

PHPでは

$ php -r "var_dump(-155/10);"
float(-15.5)

なるほど。PostgreSQLはint同士の計算をintに変換するがPHPではしないのだな。

ちょっと気になったので他の言語でもやってみる

Ruby:

irb(main):001:0> (-155/10).floor
=> -16
irb(main):002:0> -155/10
=> -16

Python:

>>> import math
>>> math.floor(-155/10)
-16.0
>>> -155/10
-16
# -15になる処理系も確認されている。詳細不明

JavaScript:

> -155/10
-15.5
> Math.floor(-155/10)
-16

JavaScriptにはそもそもNumberという概念しかないから型変換もクソもないようだ。