modulo of a number - python vs c# - c#

Lets take the basic arithmetic operation - modulo
I get different outputs depending on different languages.
Python
>>> -1 % 12
11
C#
var res = -1 % 12;
output: res = -1
Why am I seeing such behaviour? Ideally I'd like the output to be 11 in both cases.
Also does anyone know if I can achieve this in C#?

The premise of the question is incorrect. The % operator in C# is not the modulus operator, it is the remainder operator, while in Python it is a modulus operator.
As Eric Lippert Describes, modulus and remainder are the same for all positive numbers, but they handle negative numbers differently.
Despite both C# and Python having a % operator, doesn't mean they both represent a modulus.
It's worth noting that other languages, such as C++ and Java use remainder for the % operator, not modulus, which likely contributed to why C# choose to use remainder as well. Since there isn't a lot of consistency in what is meant by the % operator, I would suggest looking it up in the language docs whenever working with a new language.

In Python, the % operator returns the same sign as the divisor. In C#, it returns the same sign as the dividend. (Also see Modulo operator)
In Python, math.fmod would give similar results to C#.
If you want to obtain 11 in C#, you probably need to say:
(((-1 % 12) + 12) % 12)

Others have explained why you are getting different results in the two languages, but it's important to realize that both answers are correct in the sense that, when you reverse the operations, you get back the original number.
In C#, the result of the integer division -1 / 12 is 0. 0 * 12 is 0. To get back to the original -1, you need to add -1, which is what you got for the remainder operation.
In Python, -1 / 12 is -1. -1 * 12 is -12. To get back to the original -1, you need to add 11. Which, again, is what you got for modulus.
So it's not merely a difference in what operation % performs, there's also a difference in how integer division is performed when the signs of the operands differ between the two languages. The behavior of % is chosen so that the quotient, multiplied by the divisor, and added to the remainder, results in the dividend. Changing how the quotient is calculated necessarily changes how the remainder is calculated.

Related

Why does the modulo operator behave differently from mathematical faction MOD

There is an anomaly between the usual approach and the programming approach in the division of a negative number by a negative number as mentioned in the pictures bellow.
Mathematical demonstration of anomaly: (Sorry for bad handwriting :) Hope it is readable)
C#'s approach to division between two negative numbers:
How do I enforce C# to follow the fraction concept when I divide two negative numbers with the usual syntax? And please do not suggest me with the following algorithm:
// 'num1' and 'num2' are the two numbers of 'int' data-type to be divided where Math.Abs(num1) > Math.Abs(num2)
if (num1<0 && num2<0) // both numbers are negative
Console.WriteLine(Math.Abs(num1)%Math.Abs(num2));
else
Console.WriteLine(num1%num2);
PS: Please note that no elaboration is required in the mathematic anomaly regarding the two answers yielded by the division between two negative numbers. Just suggest me a way to enforce C# to follow the fraction concept mentioned above (if possible).
PPS: An explanation to why programming languages follow the normal division approach instead of fraction concept would be helpful too :)
EDIT: Code of the C# Approach picture above (for people who find images tough to read :) )
// Tests to see C#'s return values for signed and unsigned "modular division"
Console.WriteLine("-10 MOD 3 = "+ ((-10)%(3))); // Displays -1 (as expected)
Console.WriteLine("10 MOD -3 = "+ ((10)%(-3))); // Displays 1 (as expected)
Console.WriteLine("10 MOD 3 = "+ ((10)%(3))); // Displays 1 (as expected)
Console.WriteLine("-10 MOD -3 = "+ ((-10)%(-3))); // Displays -1 (should have displayed a positive 1)
Console.WriteLine("-10 MOD -3 (with no brackets placed for numbers) = "+ (-10%-3)); // Same output as that of above statement i.e. -1
UPDATE: Considering the opinions of the Stack Overflow community, I believe that no programming language can be enforced to follow the "fraction concept". But anyone in the community is welcome to contribute their opinions on "Why programming languages use the 'division approach' ?" question. Also please post the solution if anyone finds a way to enforce the "fraction concept" in C# in near future. Thanks. :)
(-10) % (-3) = ( (-9) + (-1) ) % (-3)
= ( 3*(-3) + (-1) ) % (-3)
= (3*(-3)) % (-3) + (-1) % (-3)
= 0 + (-1) % (-3)
so -10 mod -3 = -1 mod -3
please compare with the spec of C#'s % operator...
Note that as mathematician, i would not do a mod b with b<0...

Is Math.Abs(x) < double.Epsilon equivalent to Math.Abs(x) == 0d?

After a bit of light reading, this article piqued my interest:
I'd have thought that yes, the two statements are equivalent, given MSDN's statement:
Represents the smallest positive Double value that is greater than zero. This field is constant.
Curious to see what people think.
EDIT: Found a computer with VS on and ran this Test. Turns out that yes, as expected, they're equivalent.
[Test]
public void EpsilonTest()
{
Compare(0d);
Compare(double.Epsilon);
Compare(double.Epsilon * 0.5);
Compare(double.NaN);
Compare(double.PositiveInfinity);
Compare(double.NegativeInfinity);
Compare(double.MaxValue);
Compare(double.MinValue);
}
public void Compare(double x)
{
Assert.AreEqual(Math.Abs(x) == 0d, Math.Abs(x) < double.Epsilon);
}
IL code seems to cast some light on this.
Epsilon is simply a double number with the fraction part being 1, sign 0, exponent 0.
Zero is a double number with the fraction part being 0, sign 0, exponent 0.
According to http://en.wikipedia.org/wiki/IEEE_754-1985, floating point numbers with the same sign and exponent are compared ordinally, which means that (x < 1) is the same as (x == 0).
Now, is it possible to get a zero that isn't fraction = 0, exponent = 0 (we don't care about sign, there's a Math.Abs in place)?
Yes, as far as I can tell they should be equivalent. This is because no difference can have a magnitude less than epsilon and also be nonzero.
My only thought was concerning values such as double.NaN, I tested that and PositiveInfinity, etc. and the results were the same. By the way, comparing double.NaN to a number returns false.
I'm not sure what you mean by "equivalent" here, as that's a pretty vague term.
If you mean, will .NET consider any value less than double.Epsilon to be equal to 0d, then yes, as the article you linked to clearly demonstrates. You can show this pretty easily:
var d1 = 0d;
var d2 = double.Epsilon * 0.5;
Console.WriteLine("{0:r} = {1:r}: {2}", d1, d2, d1.Equals(d2));
// Prints: 0 = 0: True
In that sense, if you somehow produce a value of x that is less than double.Epislon, it will already be stored in-memory as a zero value, so Abs(x) will just be Abs(0) which is, == 0d.
But this is a limitation of the binary representation as used by .NET to hold floating point numbers: it simply can't represent a non-zero number smaller than double.Epsilon so it rounds.
That doesn't mean the two statements are "equivalent", because that's entirely context-dependent. Clearly, 4.94065645841247E-324 * 0.5 is not zero, it is 2.470328229206235e-324. If you are doing calculations that require that level of precision, than no, they are not equivalent -- and you're also out of luck trying to do them in C#.
In most cases, the value of double.Epsilon is entirely too small to be of any value, meaning that Abs(x) should == 0d for values much larger than double.Epison, but C# relies on you to figure that out; it will happily do the calculations down to that precision, if asked.
Unfortunately, the statement "Math.Abs(x) < double.Epsilon is equivalent to Math.Abs(x) == 0d" is not true at all for ARM systems.
MSDN on Double.Epsilon contradicts itself by stating that
On ARM systems, the value of the Epsilon constant is too small to be detected, so it equates to zero.
That means that on ARM systems, there are no non-negative double values less than Double.Epsilon, so the expression Math.Abs(x) < double.Epsilon is just another way to say false.

Why does -2 % 360 give -2 instead of 358 in c#

Microsoft Mathematics and Google's calculator give me 358 for -2 % 360, but C# and windows calculator are outputting -2 ... which is the right answer ?
The C# compiler is doing the right thing according to the C# specification, which states that for integers:
The result of x % y is the value produced by x – (x / y) * y.
Note that (x/y) always rounds towards zero.
For the details of how remainder is computed for binary and decimal floating point numbers, see section 7.8.3 of the specification.
Whether this is the "right answer" for you depends on how you view the remainder operation. The remainder must satisfy the identity that:
dividend = quotient * divisor + remainder
I say that clearly -2 % 360 is -2. Why? Well, first ask yourself what the quotient is. How many times does 360 go into -2? Clearly zero times! 360 doesn't go into -2 at all. If the quotient is zero then the remainder must be -2 in order to satisfy the identity. It would be strange to say that 360 goes into -2 a total of -1 times, with a remainder of 358, don't you think?
Which is the right answer?
Both answers are correct. It's merely a matter of convention which value is returned.
Both, see Modulo operation on Wikipedia.
I found this very easy to understand explanation at http://mathforum.org/library/drmath/view/52343.html
There are different ways of thinking about remainders when you deal
with negative numbers, and he is probably confusing two of them. The
mod function is defined as the amount by which a number exceeds the
largest integer multiple of the divisor that is not greater than that
number. In this case, -340 lies between -360 and -300, so -360 is the
greatest multiple LESS than -340; we subtract 60 * -6 = -360 from -340
and get 20:
-420 -360 -300 -240 -180 -120 -60 0 60 120 180 240 300 360
--+----+----+----+----+----+----+----+----+----+----+----+----+----+--
| | | |
-360| |-340 300| |340
|=| |==|
20 40
Working with a positive number like 340, the multiple we subtract is
smaller in absolute value, giving us 40; but with negative numbers, we
subtract a number with a LARGER absolute value, so that the mod
function returns a positive value. This is not always what people
expect, but it is consistent.
If you want the remainder, ignoring the sign, you have to take the
absolute value before using the mod function.
Doctor Peterson, The Math Forum
http://mathforum.org/dr.math/
IMO, -2 is much easier to understand and code with. If you divide -2 by 360, your answer is 0 remainder -2 ... just as dividing 2 by 360 is 0 remainder 2. It's not as natural to consider that 358 is also the remainder of -2 mod 360.
From wikipedia:
if the remainder is nonzero, there are two possible choices for the
remainder, one negative and the other positive, and there are also two
possible choices for the quotient. Usually, in number theory, the
positive remainder is always chosen, but programming languages choose
depending on the language and the signs of a and n.[2] However, Pascal
and Algol68 do not satisfy these conditions for negative divisors, and
some programming languages, such as C89, don't even define a result if
either of n or a is negative.

How do you calculate if a number is a multiple of another number(well sort of)

Please i'm in a bit of fix. I have a number, say 9 and i would like to figure out how to write a program to calculate if an unknown number is maybe 21(ie 9+12) or 30(i.e 9+12) and so on
Use the % operator and check if the result is 0 (multiple) or not zero (not multiple)
http://msdn.microsoft.com/en-us/library/0w4e0fzs%28v=vs.80%29.aspx
The answer from Aleadam is correct but the link appears to have broken. Putting a little more context
The % Operator will find the mathematical remainder so if the numbers are multiples the remainder will be 0
% Operator is the following format
dividend % divisor
For example
SELECT 9%3 will return "0" because 9 is a multiple of 3
SELECT 7%3 will return "1" because 3 does not go into 7 and instead has a mathematical remainder of 1/3
SELECT 7 / 3 AS Integer, 7 % 3 AS Remainder;

Get number of digits in an unsigned long integer c#

I'm trying to determine the number of digits in a c# ulong number, i'm trying to do so using some math logic rather than using ToString().Length. I have not benchmarked the 2 approaches but have seen other posts about using System.Math.Floor(System.Math.Log10(number)) + 1 to determine the number of digits.
Seems to work fine until i transition from 999999999999997 to 999999999999998 at which point, it i start getting an incorrect count.
Has anyone encountered this issue before ?
I have seen similar posts with a Java emphasis # Why log(1000)/log(10) isn't the same as log10(1000)? and also a post # How to get the separate digits of an int number? which indicates how i could possibly achieve the same using the % operator but with a lot more code
Here is the code i used to simulate this
Action<ulong> displayInfo = number =>
Console.WriteLine("{0,-20} {1,-20} {2,-20} {3,-20} {4,-20}",
number,
number.ToString().Length,
System.Math.Log10(number),
System.Math.Floor(System.Math.Log10(number)),
System.Math.Floor(System.Math.Log10(number)) + 1);
Array.ForEach(new ulong[] {
9U,
99U,
999U,
9999U,
99999U,
999999U,
9999999U,
99999999U,
999999999U,
9999999999U,
99999999999U,
999999999999U,
9999999999999U,
99999999999999U,
999999999999999U,
9999999999999999U,
99999999999999999U,
999999999999999999U,
9999999999999999999U}, displayInfo);
Array.ForEach(new ulong[] {
1U,
19U,
199U,
1999U,
19999U,
199999U,
1999999U,
19999999U,
199999999U,
1999999999U,
19999999999U,
199999999999U,
1999999999999U,
19999999999999U,
199999999999999U,
1999999999999999U,
19999999999999999U,
199999999999999999U,
1999999999999999999U
}, displayInfo);
Thanks in advance
Pat
log10 is going to involve floating point conversion - hence the rounding error. The error is pretty small for a double, but is a big deal for an exact integer!
Excluding the .ToString() method and a floating point method, then yes I think you are going to have to use an iterative method but I would use an integer divide rather than a modulo.
Integer divide by 10. Is the result>0? If so iterate around. If not, stop.
The number of digits is the number of iterations required.
Eg. 5 -> 0; 1 iteration = 1 digit.
1234 -> 123 -> 12 -> 1 -> 0; 4 iterations = 4 digits.
I would use ToString().Length unless you know this is going to be called millions of times.
"premature optimization is the root of all evil" - Donald Knuth
From the documentation:
By default, a Double value contains 15
decimal digits of precision, although
a maximum of 17 digits is maintained
internally.
I suspect that you're running into precision limits. Your value of 999,999,999,999,998 probably is at the limit of precision. And since the ulong has to be converted to double before calling Math.Log10, you see this error.
Other answers have posted why this happens.
Here is an example of a fairly quick way to determine the "length" of an integer (some cases excluded). This by itself is not very interesting -- but I include it here because using this method in conjunction with Log10 can get the accuracy "perfect" for the entire range of an unsigned long without requiring a second log invocation.
// the lookup would only be generated once
// and could be a hard-coded array literal
ulong[] lookup = Enumerable.Range(0, 20)
.Select((n) => (ulong)Math.Pow(10, n)).ToArray();
ulong x = 999;
int i = 0;
for (; i < lookup.Length; i++) {
if (lookup[i] > x) {
break;
}
}
// i is length of x "in a base-10 string"
// does not work with "0" or negative numbers
This lookup-table approach can be easily converted to any base. This method should be faster than the iterative divide-by-base approach but profiling is left as an exercise to the reader. (A direct if-then branch broken into "groups" is likely quicker yet, but that's way too much repetitive typing for my tastes.)
Happy coding.

Categories