「PHPとPostgreSQLに投げて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をかける前の値が何になっているか調べてみる。
# 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
>>> import math >>> math.floor(-155/10) -16.0 >>> -155/10 -16 # -15になる処理系も確認されている。詳細不明
JavaScript:
> -155/10 -15.5 > Math.floor(-155/10) -16
JavaScriptにはそもそもNumberという概念しかないから型変換もクソもないようだ。