了解 Oracle 中 remainder() 函数的行为

Understanding behavior of remainder() function in Oracle

根据余数 (n2,n1) 函数 (https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions133.htm) 的 Oracle 文档,余数 (n2,n1) 函数的计算结果为 = n2 - n1 * N,其中 N = ROUND(n2/n1) 和 n1 != 0.

所以,我希望余数 (10,4) 到 return -2 使用上面记录的计算余数的方法,如下所示:

REMAINDER(10,4)
=10 - 4 * N where N = ROUND(10/4) 
=10 - 4 * 3 since ROUND(10/4) = 3 
=10 - 12
=-2

但是,运行 Oracle 10g、11g 和 12c 中的 remainder(10,4) returns 2 而不是 -2。

有人可以解释为什么余数 (10,4) 没有按照 oracle 如何计算余数的记录方法进行计算吗?

附加信息:此行为每隔 n2 发生一次,其中 n2 是 n1 / 2 的倍数。可以通过 运行 以下 SQL 验证,其中每个余数函数值应与旁边的值。但它只匹配 n2 的所有其他值。 运行 SQL:

select
remainder(2,4), 2-4*round(2/4),--OUTPUT:2, -2
remainder(6,4),6-4*round(6/4), --OUTPUT: -2, -2
remainder(10,4),10-4*round(10/4),--OUTPUT: 2, -2
remainder(14,4),14-4*round(14/4)--OUTPUT: -2, -2
from dual 

编写文档的人(他们似乎不记得数学中的一些定义)自己似乎不确定他们写的是什么。一方面,在解释的早期他们确实提到了 ROUND - 但后来当他们给出更正式的定义时他们说

•If n1 != 0, then the remainder is n2 - (n1*N) where N is the integer nearest n2/n1

"Integer nearest" 在算术中没有正式定义,实际上允许将那个名称用于 round(x),除非 x 的小数部分正好是 0.5,在这种情况下 "integer nearest"是模棱两可的,人们可以选择使用 "round down" 作为他们自己对 "integer nearest."

的定义

如果可以的话,不要对文档中的此类不一致感到太生气。你会看到更多。

但是:更糟糕的是行为不一致。我使用的是 Oracle 12.1,在我的机器上我刚刚试了一下,我得到了

remainder(10, 4) =  2
remainder( 6, 4) = -2

无韵无理。使用 FLOOR 等进行自己的划分要好得多。

编辑 - 或者可能有一些原因;也许他们使用 "nearest integer" 的定义来表示,在平局的情况下,最接近的 even 整数。仍然产生意想不到的结果,最好不要使用 Oracle 的 REMAINDER() 函数。