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

MySQL MOD()坏了:这是最好的选择吗?,mysql,modulus,Mysql,Modulus,至少在MySQL v5.1.73(CentOS 6.6)中,MOD()函数返回一个虚假结果。。。除非有人能解释这到底是怎么回事 mysql> select MOD(-385.4784399 ,1440); +-------------------------+ | MOD(-385.4784399 ,1440) | +-------------------------+ | -385.4784399 | +-------------------------+ 1 ro

至少在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并没有给你一个虚假的结果,它只是使用了不同于你预期的模实现。不幸的是,术语模的定义似乎有点含糊不清,它的实现因语言而异。从中可以看出,MySQL的实现使用了截断除法:

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

您希望实现使用地板分区的地方

r=a-n*楼层(a/n)

由于这是您实现第一个变通方法的方式,我认为它可能是
Mod
操作符的最佳替代方法


据我所见(这是一个非常快速的非科学分析!),似乎更多的命令式编程语言实现了截断除法,而更多的函数式数学语言似乎使用了截断除法

,除非有一些您可以引用的不符合的规范,否则它不会被破坏。它在文档中被定义为余数,并且没有给出第一个参数为负的示例。您期望得到什么结果?MOD是模运算,返回
-385.478439885319
除以
1440
的余数。模运算的结果不能大于除数。这是基本的模运算,我希望得到正确的答案。。。我甚至展示了正确的答案;我只是不确定这是最有效的方法。Google calculator同意@tlum C#不:
-385.4784399%1440==-385.4784399
MySQL给出了一个数学上不正确的解决方案;这是因为截断除法有缺陷。欧几里德定理可以追溯到2000多年前。今天,计算器试图用现代计算机科学的定理来捕捉它的本质,但有些实现比其他实现做得更完整。“尽管截断除法被广泛使用,但它却不如其他定义。”——Leijen,Daan(2001年12月3日)。检索日期:2015-06-09。