【发布时间】:2014-06-27 10:07:24
【问题描述】:
虽然这两个函数执行相同的操作,即使它们产生相同的 o/p,这两者之间的基本区别是什么?是否有任何与性能相关的差异,如果有,那么哪个更好?
谢谢
【问题讨论】:
虽然这两个函数执行相同的操作,即使它们产生相同的 o/p,这两者之间的基本区别是什么?是否有任何与性能相关的差异,如果有,那么哪个更好?
谢谢
【问题讨论】:
documentation 的区别非常明显:
注意
REMAINDER 函数在其公式中使用舍入函数,而 MOD函数在其公式中使用了地板函数。
换句话说,当参数是正整数时,mod 函数返回一个介于 0 和第二个参数之间的正数。余数函数返回一个绝对值小于第二个参数除以 2 的数字。
对于负数,差异可能会更加显着。差异的一个例子是:
REMAINDER(-15, 4)
MOD(-15, 4)
第一个给出-3,第二个给出1。
编辑:
这里发生了什么? 4进入-15多少次。一种方法是“-4”次,余数为 1。即:-15 = 4*(-4) + 1。另一种方法是“-3”次:-15 = 4*(-3) - 3。
-15/4 表示为整数的区别。使用地板,您会得到-4。使用round,你会得到-3。
【讨论】:
MOD和REMAINDER函数的区别可以通过下面的例子来理解:
MOD(13,5): 返回 3 而 REMAINDER (13,5) 返回 -2
理解差异的一个简单方法是 MOD 使用 floor 函数,因此它计算第一个数字中第二个数字的出现次数并返回完成第一个数字的剩余部分,即 2(5) 得到 10 加 3 得到 13因此 MOD(13,5)=3
但是,REMAINDER 使用 Round 函数,因此它获取可以构成第一个数字的第二个数字的总数,然后减去使其超出的部分。即 3(5) = 15 减去 2 得到 13,因此 REMAINDER(13,5)= -2
REMAINDER (-15, 4): 4(-4) 得到 -16,加上 +1 得到 -15 因此 REMAINDER (-15,4)=+1
MOD (-15, 4): 3(-4) 得到 -12,加上 -3 得到 -15 因此 MOD(15,4)=-3
【讨论】:
REMAINDER(-15, 4)--使用round而不带数字的符号 考虑。
因此 -15/4= -3.75==> round(-3.75)= -4.--(在回合中忽略符号)
-4*4= -16
-15-(-16)=>1
因此:剩余(-15, 4)=1
MOD(-15, 4)----使用Floor而不带数字的符号 考虑。
-15/4= -3.75==> floor(-3.75)= -3.--(ignore sign in floor)
-3*4=-12
-15-(-12)=>-3
因此:MOD(-15, 4)= -3
【讨论】:
Mod(m,n) 很容易理解。
求值 mod() 的输出值将始终是我们将 m 除以 n 时手动计算的余数。
寻找符号输出的符号与第一个参数保持一致。
例如:
eg 1 : mod (11,3) 是 11/3 的余数,即 2 和第一个参数的符号相同。所以输出是 2
eg 2 : mod (-11,3) 是 11/3 的余数,即 2 和第一个参数的符号相同。所以输出是-2
Remainder(m,n) 有点不同
求值 你取 n 的两个倍数,这样当相乘时,给出与第一个参数 (m) 相比最接近的下限值和最接近的上限值。这些值之间的最小差异将是输出值
寻找符号 如果最接近的值小于第一个参数,则输出值的符号始终为正,如果最接近的值大于第一个参数,则输出值的符号为负。
例如:
【讨论】:
这个问题早就有了答案,但我认为一些上下文会有所帮助。
https://en.wikipedia.org/wiki/Modulo_operation 讨论了“模”运算,以及它基于整数除法后的余数这一事实。问题是在有负数的地方没有明确定义“余数”的概念。
当涉及负数时,模数和余数之间的差异是显着的。在数学上,模运算将整数映射到一个范围。这个范围从 0 开始并且是循环的。例如integer mod 3 映射到范围:
0, 1, 2, 0, 1, 2, …
如果给定的整数是负数,则循环简单地向后扩展。但是,如果模本身为负,则整个范围为负:
0, -2, -1, 0, -2, -1, …
https://rob.conery.io/2018/08/21/mod-and-remainder-are-not-the-same/ 将此表示为带有负数的时钟。
这样做的实际结果是第二个数字的符号与结果的符号相同。
但是,如果有余数,您会尝试将第二个数字除以第一个数字,直到无法再除。剩余的差称为余数。如果第一个数字是负数,那么,如果你停下来,余数将是负数。
其实际结果是第一个数字的符号是结果的符号。
大多数编码语言(包括 SQL 的大多数变体)都使用余数计算,但通常将其称为模数。大多数语言使用a % b 表示a mod b。
当然,Oracle 有两个功能,应该会有所帮助。然而,第一个函数mod() 实际上给出了其他人所说的余数。第二个,remainder() 给出了其他人没有给出的结果,因为它专注于 最近 部门。根据文档,mod() 函数使用floor() 函数,而remainder() 使用round()。
如果你想比较结果,你可以试试:
SELECT
remainder(19,5) AS "Remainder ++",
remainder(-19,5) AS "Remainder -+",
remainder(19,-5) AS "Remainder +-",
remainder(-19,-5) AS "Remainder --",
mod(19,5) AS "Mod ++",
mod(-19,5) AS "Mod -+",
mod(19,-5) AS "Mod +-",
mod(-19,-5) AS "Mod --",
mod(mod(19,5) + 5,5) AS "Modulo ++",
mod(mod(-19,5) + 5,5) AS "Modulo ++",
mod(mod(19,-5) + -5,-5) AS "Modulo ++",
mod(mod(-19,-5) + -5,-5) AS "Modulo ++"
FROM DUAL
;
modulo 计算给出真实模数,根据https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder
总而言之,您可能希望 余数 作为最自然的解释,因此您将使用 mod() 来获得此结果。
【讨论】: