至少在 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)
最佳答案
MySQL 并没有给你一个虚假的结果,它只是使用了与你预期不同的模数实现。不幸的是,模数一词的定义似乎有些含糊,而且它的实现因语言而异。从我在 Wikipedia on Modulo 中可以看出,MySQL的实现是使用截断除法:
r = a - n * trunc(a/n)
您期望实现使用地板划分的地方:
r = a - n * 楼层(a/n)
既然您是这样实现第一个解决方法的,我想说它可能是 Mod
运算符的最佳替代方案。
从我所看到的(这是一个非常快速的不科学的分析!),似乎更多的命令式编程语言实现了截断除法,而更多的函数式数学语言似乎使用floored部门。
关于MySQL MOD() 已损坏 : Is this the best alternative?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30733829/