What is the difference between MOD and REMAINDER in oracle? - sql

Although both the functions perform the same operation, even they produce same o/p, what is basic difference between these two? Is there any performance related difference, if yes, then which one is better?
Thanks

The documentation is pretty clear on the difference:
NOTE
The REMAINDER function uses the round function in its formula, whereas
the MOD function uses the floor function in its formula.
In other words, when the arguments are positive integers, the mod function returns a positive number between 0 and the second argument. The remainder function returns a number whose absolute value is less than the second argument divided by 2.
The differences can be more striking for negative numbers. One example of a difference is:
REMAINDER(-15, 4)
MOD(-15, 4)
The first gives -3 and the second 1.
EDIT:
What is happening here? How many times does 4 go into -15. One method is "-4" times with a remained of 1. That is: -15 = 4*(-4) + 1. The other is "-3" times: -15 = 4*(-3) - 3.
The difference what is -15/4 expressed as an integer. Using floor, you get -4. Using round, you get -3.

The difference between MOD and REMAINDER function can be understood in the example below:
MOD(13,5): returns 3 whereas, REMAINDER (13,5) returns -2
A simple way to understand the difference is that MOD uses the floor function therefore it counts the occurrence of the second number within the first and returns what is left to complete the first number i.e. 2(5) gives 10 adding 3 gives 13 therefore MOD(13,5)=3
However, the REMAINDER uses a Round function it therefore gets the total number of the second number that could make up the first and then subtract the what makes it excess. i.e. 3(5) = 15 and subtracting 2 gives 13,therefore REMAINDER(13,5)= -2
REMAINDER (-15, 4): 4(-4) gives -16 and adding +1 gives -15 hence REMAINDER (-15,4)=+1
MOD (-15, 4): 3(-4) gives -12, adding -3 gives us -15 hence MOD(15,4)=-3

REMAINDER(-15, 4)--uses round without taking the sign of the number into
consideration.
hence -15/4= -3.75==> round(-3.75)= -4.--(ignore sign during round)
-4*4= -16
-15-(-16)=>1
There fore: REMAINDER(-15, 4)=1
MOD(-15, 4)----uses Floor without taking the sign of the number into
consideration.
-15/4= -3.75==> floor(-3.75)= -3.--(ignore sign in floor)
-3*4=-12
-15-(-12)=>-3
There fore: MOD(-15, 4)= -3

Mod(m,n) is so simple to understand.
Finding Value Mod() output value will always be the manually calculated remainder value when we divide m by n.
Finding Sign The sign of the output remains the same as the first parameter.
eg :
eg 1 : mod (11,3) is the remainder of 11/3 which is 2 and the same sign of 1st parameter. So output is 2
eg 2 : mod (-11,3) is the remainder of 11/3 which is 2 and the same sign of the 1st parameter. So the output is -2
Remainder(m,n) is a bit different
Finding Value You take two multiples of n, such that when multiplied gives the closest lower value and the closest upper value compared to the first parameter(m). The minimum difference between these values will be the output value
Finding Sign The sign of the output value will always be positive if the closest value is less than the first parameter and the if the closest value is greater than the 1st parameter then it will be negative.
eg :
eg 1 : remainder(10,3) The closest multiple values of 3 which are lesser and greater than 10 are 9(3x3) and 12(3x4). And the closest to 10 among 9 & 12 is 9. So the output will be the gap between 9 and 10 which is 1. The closest number is less than the 1st parameter. So the output is 1.
eg 2 : remainder(11,3) The closest multiple values of 11 which are lesser and greater than 11 are 9(3x3) and 12(3x4). And the closest to 12 among 9 & 12 is 12. So the output will be the gap between 12 and 11 which is 1. The closest number is greater than the 1st parameter. So the output is -1.

The question has long had an answer, but I thought some context would be helpful.
https://en.wikipedia.org/wiki/Modulo_operation discusses the “modulo” operation, and the fact that it is based on the remainder after integer division. The problem is that the concept of “remainder” is not clearly defined where there are negative numbers.
Where negative numbers are involved, the difference between modulus and remainder is significant. Mathematically, the modulus operation maps an integer on to a range. This range begins at 0 and is cyclic. For example integer mod 3 is mapped on to the range:
0, 1, 2, 0, 1, 2, …
If the given integer is negative, the cycle is simply extended backwards. If, however, the modulus itself is negative, then the whole range is negative:
0, -2, -1, 0, -2, -1, …
https://rob.conery.io/2018/08/21/mod-and-remainder-are-not-the-same/ illustrates this as a clock with negative numbers.
The practical upshot of this is that the sign of the second number is the same as the sign of the result.
With a remainder, however, you attempt to divide the second number into the first number until you can’t go any more. The remaining difference is called the remainder. If the first number is negative, then, if you stop short, the remainder will be negative.
The practical upshot of which is that the sign of the first number is the sign of the result.
Most coding languages, including most variations of SQL, use a remainder calculation, but very often call it the modulus. And most languages use the notation a % b meaning a mod b.
Oracle, of course, has two functions, which should have been helpful. However, the first function, mod(), actually gives what everybody else calls the remainder. The second, remainder() gives a result which nobody else gives, due to the fact that it is focused on the nearest division. As per the documentation, the mod() functions uses the floor() function, while remainder() uses round().
If you want to compare the results, you can try:
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
;
The modulo calculation gives the true modulus, according to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder
In all, you probably want the remainder as the most natural interpretation, and so you will use mod() to get this result.

Related

How do I calculate the sum efficiently?

Given an integer n such that (1<=n<=10^18)
We need to calculate f(1)+f(2)+f(3)+f(4)+....+f(n).
f(x) is given as :-
Say, x = 1112222333,
then f(x)=1002000300.
Whenever we see a contiguous subsequence of same numbers, we replace it with the first number and zeroes all behind it.
Formally, f(x) = Sum over all (first element of the contiguous subsequence * 10^i ), where i is the index of first element from left of a particular contiguous subsequence.
f(x)=1*10^9 + 2*10^6 + 3*10^2 = 1002000300.
In, x=1112222333,
Element at index '9':-1
and so on...
We follow zero based indexing :-)
For, x=1234.
Element at index-'0':-4,element at index -'1':3,element at index '2':-2,element at index 3:-1
How to calculate f(1)+f(2)+f(3)+....+f(n)?
I want to generate an algorithm which calculates this sum efficiently.
There is nothing to calculate.
Multiplying each position in the array od numbers will yeild thebsame number.
So all you want to do is end up with 0s on a repeated number
IE lets populate some static values in an array in psuedo code
$As[1]='0'
$As[2]='00'
$As[3]='000'
...etc
$As[18]='000000000000000000'```
these are the "results" of 10^index
Given a value n of `1234`
```1&000 + 2&00 +3 & 0 + 4```
Results in `1234`
So, if you are putting this on a chip, then probably your most efficient method is to do a bitwise XOR between each register and the next up the line as a single operation
Then you will have 0s in all the spots you care about, and just retrive the values in the registers with a 1
In code, I think it would be most efficient to do the following
```$n = arbitrary value 11223334
$x=$n*10
$zeros=($x-$n)/10```
Okay yeah we can just do bit shifting to get a value like 100200300400 etc.
To approach this problem, it could help to begin with one digit numbers and see what sum you get.
I mean like this:
Let's say, we define , then we have:
F(1)= 45 # =10*9/2 by Euler's sum formula
F(2)= F(1)*9 + F(1)*100 # F(1)*9 is the part that comes from the last digit
# because for each of the 10 possible digits in the
# first position, we have 9 digits in the last
# because both can't be equal and so one out of ten
# becomse zero. F(1)*100 comes from the leading digit
# which is multiplied by 100 (10 because we add the
# second digit and another factor of 10 because we
# get the digit ten times in that position)
If you now continue with this scheme, for k>=1 in general you get
F(k+1)= F(k)*100+10^(k-1)*45*9
The rest is probably straightforward.
Can you tell me, which Hackerrank task this is? I guess one of the Project Euler tasks right?

Why does round(143.23,-1) return 140?

For the query
SELECT round(143.23, -1)
FROM dual
I thought that the output will be 142 but the output i got is 140
can anyone help me by explaining this.
The second parameter indicates how many digits of precision after the decimal point you want to preserve. Thus, -1 means one digit before the decimal point. I.e., you're losing the "ones" digit and rounding to the nearest "tens", resulting in 140.
To get a whole number (143 in this case), you can pass 0 as the second parameter, or just omit it entirely, as that's the default.

Error taking int of logs in VBA

When I calculate log(8) / log(2) I get 3 as one would expect:
?log(8)/log(2)
3
However, if I take the int of this calculation like this the result is 2 and thus wrong:
?int(log(8)/log(2))
2
How and why does this happen?
Likely because the actual number returned is of type double. Because floats and doubles cannot accurately represent most base 10 rational numbers the number returned is something like 2.99999999999. Then when you apply int() the .999999999 is truncated.
How floating-point number works: it dedicates a bit for the sign, a few bits to store an exponent, and the rest for the actual fraction. This leads to numbers being represented in a form similar to 1.45 * 10^4; except that instead of the base being 10, it's two.

Which one is the correct way of using "arc4rand()"

I am new to objective C and trying to understand arc4random().
There are so many conflicting explanations on the web. Please clear my confusion, which of the following is correct:
// 1.
arc4random() % (toNumber - fromNumber) + fromNumber;
OR
//2.
arc4random() % ((toNumber - fromNumber) + 1) + fromNumber;
//toNumber-fromNumbers are any range of numbers like random # between 7-90.
This code will get you a random number between 7 and 90.
NSUInteger random = 7 + arc4random_uniform(90 - 7);
Use arc4random_uniform to avoid modulo bias.
Adam's answer is correct. However, just to clarify the difference between the two, the second one raises the possible range by one to make the range inclusive. The important thing to remember is that modulo is remainder division, so while there are toNumber possible outcomes, one of them is zero (if the result of arc4random() is a multiple of toNumber) and toNumber itself can not be the remainder.
// 1.
arc4random() % (10 - 5) + 5;
This results in a range of 0 + 5 to 4 + 5, which is 5 to 9.
//2.
arc4random() % ((10 - 5) + 1) + 5;
This results in a range of 0 + 5 to (4 + 1) + 5, which is 5 to 10.
Neither is correct or incorrect if you wish to use modulo. One is exclusive of the upper range while the other is inclusive of the upper range. However, if you think about how remainder division works and think of the pool of numbers returned by any PRNG in terms of cycles the length of your total range, then you'll realize that if the range does not divide evenly into the maximum range of the pool you'll get biased results. For instance, if arc4random() returned a result from 1 to 5 (it doesn't, obviously) and you wanted a number from 0 to 2, and you used arc4random() % 3, these are the possible results.
1 % 3 = 1
2 % 3 = 2
3 % 3 = 0
4 % 3 = 1
5 % 3 = 2
Note that there are two ones and two twos, but only one zero. This is because our range of 3 does not evenly divide into the PRNG's range of 5. The result is that (humorously enough) PRNG range % desired range numbers at the end of the cycle need to be culled because they are "biased"–the numbers themselves aren't really biased, but it's easier to cull from the end. Failing to do this results in the lower numbers of the range becoming more likely to appear.
We can cull the numbers by calculating the upper range of the numbers we can generate, modulo it with the desired range and then pull those numbers off of the end. By "pull those numbers off of the end" I really mean "loop infinitely until we get a number that isn't one of the end numbers".
Some would say that's bad practice; you could theoretically loop forever. In practice, however, the expected number of retries is always less than one since the modulo bias is never more than half the pool (usually much less than that) of the PRNG's numbers. I once wrote a wrapper for rand using this technique.
You can see an example of this in the source for OpenBSD, where arc4random_uniform calls arc4random in a loop until a number is determined to be clean.

Weird Objective-C Mod Behavior for Negative Numbers

So I thought that negative numbers, when mod'ed should be put into positive space... I cant get this to happen in objective-c
I expect this:
-1 % 3 = 2
0 % 3 = 0
1 % 3 = 1
2 % 3 = 2
But get this
-1 % 3 = -1
0 % 3 = 0
1 % 3 = 1
2 % 3 = 2
Why is this and is there a workaround?
result = n % 3;
if( result < 0 ) result += 3;
Don't perform extra mod operations as suggested in the other answers. They are very expensive and unnecessary.
In C and Objective-C, the division and modulus operators perform truncation towards zero. a / b is floor(a / b) if a / b > 0, otherwise it is ceiling(a / b) if a / b < 0. It is always the case that a == (a / b) * b + (a % b), unless of course b is 0. As a consequence, positive % positive == positive, positive % negative == positive, negative % positive == negative, and negative % negative == negative (you can work out the logic for all 4 cases, although it's a little tricky).
If n has a limited range, then you can get the result you want simply by adding a known constant multiple of 3 that is greater that the absolute value of the minimum.
For example, if n is limited to -1000..2000, then you can use the expression:
result = (n+1002) % 3;
Make sure the maximum plus your constant will not overflow when summed.
We have a problem of language:
math-er-says: i take this number plus that number mod other-number
code-er-hears: I add two numbers and then devide the result by other-number
code-er-says: what about negative numbers?
math-er-says: WHAT? fields mod other-number don't have a concept of negative numbers?
code-er-says: field what? ...
the math person in this conversations is talking about doing math in a circular number line. If you subtract off the bottom you wrap around to the top.
the code person is talking about an operator that calculates remainder.
In this case you want the mathematician's mod operator and have the remainder function at your disposal. you can convert the remainder operator into the mathematician's mod operator by checking to see if you fell of the bottom each time you do subtraction.
If this will be the behavior, and you know that it will be, then for m % n = r, just use r = n + r. If you're unsure of what will happen here, use then r = r % n.
Edit: To sum up, use r = ( n + ( m % n ) ) % n
I would have expected a positive number, as well, but I found this, from ISO/IEC 14882:2003 : Programming languages -- C++, 5.6.4 (found in the Wikipedia article on the modulus operation):
The binary % operator yields the remainder from the division of the first expression by the second. .... If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined
JavaScript does this, too. I've been caught by it a couple times. Think of it as a reflection around zero rather than a continuation.
Why: because that is the way the mod operator is specified in the C-standard (Remember that Objective-C is an extension of C). It confuses most people I know (like me) because it is surprising and you have to remember it.
As to a workaround: I would use uncleo's.
UncleO's answer is probably more robust, but if you want to do it on a single line, and you're certain the negative value will not be more negative than a single iteration of the mod (for example if you're only ever subtracting at most the mod value at any time) you can simplify it to a single expression:
int result = (n + 3) % 3;
Since you're doing the mod anyway, adding 3 to the initial value has no effect unless n is negative (but not less than -3) in which case it causes result to be the expected positive modulus.
There are two choices for the remainder, and the sign depends on the language. ANSI C chooses the sign of the dividend. I would suspect this is why you see Objective-C doing so also. See the wikipedia entry as well.
Not only java script, almost all the languages shows the wrong answer'
what coneybeare said is correct, when we have mode'd we have to get remainder
Remainder is nothing but which remains after division and it should be a positive integer....
If you check the number line you can understand that
I also face the same issue in VB and and it made me to forcefully add extra check like
if the result is a negative we have to add the divisor to the result
Instead of a%b
Use: a-b*floor((float)a/(float)b)
You're expecting remainder and are using modulo. In math they are the same thing, in C they are different. GNU-C has Rem() and Mod(), objective-c only has mod() so you will have to use the code above to simulate rem function (which is the same as mod in the math world, but not in the programming world [for most languages at least])
Also note you could define an easy to use macro for this.
#define rem(a,b) ((int)(a-b*floor((float)a/(float)b)))
Then you could just use rem(-1,3) in your code and it should work fine.