MySQL MOD()坏了:这是最好的选择吗?

时间:2015-06-09 13:44:38

标签: mysql modulus

至少在MySQL v5.1.73(CentOS 6.6)中,MOD()函数返回一个伪造的结果......除非有人能解释这是如何实际的。

mysql> select MOD(-385.4784399 ,1440);
+-------------------------+
| MOD(-385.4784399 ,1440) |
+-------------------------+
|            -385.4784399 |
+-------------------------+
1 row in set (0.01 sec)

这是最好的选择吗?

mysql> select -385.478439885319 - 1440 * FLOOR(-385.478439885319/1440);
+----------------------------------------------------------+
| -385.478439885319 - 1440 * FLOOR(-385.478439885319/1440) |
+----------------------------------------------------------+
|                                        1054.521560114681 |
+----------------------------------------------------------+
1 row in set (0.00 sec)

我认为这也会有效,但是要做一些简单的事情还有很长的路要走。

mysql> select MOD((MOD(-385.478439885319, 1440) + 1440), 1440);
+--------------------------------------------------+
| MOD((MOD(-385.478439885319, 1440) + 1440), 1440) |
+--------------------------------------------------+
|                                1054.521560114681 |
+--------------------------------------------------+
1 row in set (0.00 sec)

1 个答案:

答案 0 :(得分:3)

MySQL并没有给你一个虚假的结果,它只是使用了比你预期的模数不同的实现。不幸的是,模数这个术语似乎有些含糊不清,而且它的实现因语言而异。从我在Wikipedia on Modulo中可以看出,MySQL的实现是使用截断分区

r = a - n * trunc(a / n)

您希望实施使用 floored division

r = a - n * floor(a / n)

由于您实现了第一个解决方法,我认为它可能是Mod运算符的最佳替代方案。

从我所看到的(这是一个非常快速的不科学的分析!),似乎更多命令式编程语言实现截断分割,更多功能数学语言似乎使用 floored分割