Understanding behavior of remainder() function in Oracle

自古美人都是妖i 提交于 2019-12-24 12:13:16

问题


According to Oracle documentation for the remainder(n2,n1) function (https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions133.htm), the remainder(n2,n1) function evaluates to = n2 - n1 * N where N = ROUND(n2/n1) and n1 != 0.

So, I would expect remainder(10,4) to return -2 using the above documented method of calculating the remainder as shown below:

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

However, running remainder(10,4) in Oracle 10g, 11g, and 12c returns 2 instead of -2.

Can someone please explain why the remainder(10,4) is not evaluating as per the documented method of how oracle evaluates the remainder?

Additional information: This behavior happens for every other n2 where n2 is a multiple of n1 / 2. It can be verified by running the following SQL where each remainder function value should match the value next to it. But it only matches for every other value of n2. Running the 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 

回答1:


The people who wrote the documentation (who seem not to recall some definitions from arithmetic) themselves seem unsure about what they wrote. On the one hand, early in the explanation they do mention ROUND - yet later when they give a more formal definition they say

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

"Integer nearest" is not formally defined in arithmetic, and indeed one is permitted to use that name for round(x) except when the fractional part of x is exactly 0.5, in which case "integer nearest" is ambiguous and one may choose to use "round down" as their own definition of "integer nearest."

Don't get too upset with such inconsistencies in the documentation, if you can. You will see many more.

However: What is MUCH worse is that the behavior is inconsistent. I use Oracle 12.1, and on my machine I just tried and I get

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

No rhyme or reason. Much better to do your own division, using FLOOR and such.

Edit - Or maybe there is some reason; perhaps they use a definition of "nearest integer" to mean, in the case of a tie, the nearest even integer. Still producing unexpected results, best not to use Oracle's REMAINDER() function.



来源:https://stackoverflow.com/questions/41625194/understanding-behavior-of-remainder-function-in-oracle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!