I'm experimenting with negative-base number systems, and I use Excel to play with and check my calculations.
I notice that there are differences in C# vs. Excel. Why does C# return a different result than Excel?
For example:
C#: 146 % -3 = 2
Excel: mod(146, -3) = -1
Let's suppose we have four integers: x, y, q, and r such that
q = x / y
r = x - q * y
I hope that it makes sense that the quotient and remainder must have this relationship.
Now we come to the difference between C# and Excel. The difference is actually in the division, not the remainder. When computing the quotient of two integers, C# rounds towards zero, and Excel rounds down. That is, in C# 8 / -3 is -2, and in excel, INT(8 / -3) is -3.
From that fact you can deduce why the remainders are different.
As the Wikipedia article says, a modulo operation is dividend % divisor == remainder. The problem comes when either of the operands are negative values. At that point, the naive mathematical definition breaks down and the result becomes implementation-dependent.
In Excel, the mod operator always returns a result with the same sign as the divisor. Mathematically, the quotient used in the modulo operation is rounded downwards (towards −∞). In pseudo-code:
quotient = floor(dividend / divisor)
mod = dividend - (divisor * quotient)
Therefore, for 146 and -3:
quotient = -49 // floor(146 / -3)
mod = -1 // 146 - (-3 * -49) == 146 - 147
In C#, it is the opposite: the result always has the same sign as the dividend. This is because the quotient is truncated toward 0. In pseudo-code:
quotient = truncate(dividend / divisor)
mod = dividend - (divisor * quotient)
Therefore:
quotient = -48 // truncate(146 / -3)
mod = 2 // 146 - (-3 * -48) == 146 - 144
Related
In order to create a floating point number from a decimal value, we need to have a sign bit, and exponent, and a mantissa.
Double precision uses 11 exponent bits, and 52 mantissa bits.
Let's say we want to store 0.3. We can find the mantissa by doing the following:
0.3 * 2 = 0.6 => 0
0.6 * 2 = 1.2 => 1
0.2 * 2 = 0.4 => 0
0.4 * 2 = 0.8 => 0
0.8 * 2 = 1.6 => 1
0.6 * 2 = 1.2 => 1
...
Answer:
01001100110011...
In C# I can do this with the following code:
double value = 0.3;
StringBuilder bitString = new StringBuilder();
for (int i = 0; i < 53; i++)
{
value *= 2;
if (value >= 1)
{
bitString.Append("1");
value--;
}
else
{
bitString.Append("0");
}
}
Is it possible to take an existing mantissa from a double, and continue this process to find further bits? I know this won't work for certain values, but what if I have an exact number like 0.123, and I know all the remaining digits are 0. 0.1230000000...
My code above seems to have a problem. Since I am using a double for my multiplication, I only have 15-17 digits of precision. It is possible during my multiply by 2 situation to be slightly off ending the number of bits I can accurately store. Is there away around this without needing a bigger type like System.Decimal?
The goal here is to end up with a bit string, that contains more than 53 bits of valid data.
I was working on a script in unity when i realized something odd and after I finished the script I tested my realization in a visual studio console project.
class Program
{
static void Main(string[] args)
{
Console.WriteLine(-3.5 % 1);
Console.WriteLine(3.5 % (-1));
}
}
The output was:
-0.5
0.5
Shouldn't the modulus operator give me -0.5 in both cases?
C#'s % operator is actually a remainder -- so it simply returns what's left over from the division. The most important part of that is that the remainder is only affected by the sign of the numerator, and not the divisor.
In the case of 3.5 positive, the 3 will divide perfectly, with 0.5 left over -- with -3.5, -3 will divide perfectly, with -0.5 left over. Whether you divide by -1 or 1 doesn't affect the outcome in either case, the remainder will be the same, and is only affected by the sign of the number itself.
Shouldn't the modulus operator give me -0.5 in both cases?
Why should it? Mathematically, both 0.5 and -0.5 are correct for the both cases.
-3.5 = -3 * 1 + (-0.5)
-3.5 = -4 * 1 + 0.5
3.5 = -3 * (-1) + 0.5
3.5 = -4 * (-1) + (-0.5)
Programmatically, it's defined by the C# language specification.
7.8.3 Remainder operator
Floating-point remainder:
float operator %(float x, float y);
double operator %(double x, double y);
The following table lists the results of all possible combinations of
nonzero finite values, zeros, infinities, and NaN’s. In the table, x
and y are positive finite values. z is the result of x % y and is
computed as x – n * y, where n is the largest possible integer that is
less than or equal to x / y. This method of computing the remainder is
analogous to that used for integer operands, but differs from the IEEE
754 definition (in which n is the integer closest to x / y).
The table says that the sign of the remainder is the same as the sign of the first operand x.
In the case of -3.5 % 1:
x = 3.5
y = 1
n = 3
z = 3.5 - 3 * 1 = 0.5
According to the table, the result is -z, that is -0.5.
In the case of 3.5 % -1, x, y, n, z are the same as above. According to the table, the result is +z, that is 0.5.
I have some C# application:
double n = p * q;
double S = Math.Pow(M, d) % n;
In my situation, M==7, d==27, n = 55. I calculate it in the Windows default calculator, and get 28. But my application returns 14. Why?
double has a maximum of 16 digits of precision, but 7^27 is a 23-digit number, so you are losing precision in the exponentiation. Windows calculator supports 32 digits of precision for transcendental functions (like pow), so it can perform the calculation without a loss of precision.
You could use the mathematical fact that (a^b) % N is the same an ((a%n) ^ b) % n, but you're still raining a number greater then 2 to the 27th power which can't be precisely represented in a double.
Another option is to split the power into multiple exponents that can be represented in a double without a loss of precision:
7^27 = 7^9 * 7^9 * 7^9
7^27 % 55 = ((7^9) % 55 * (7^9) % 55 * (7^9) % 55) % 55
= (52 * 52 * 52) % 55
= 140,608 % 55
= 28
As D Stanley mentioned, double only has 16 digits of precision. You need to use BigInteger. Which is in .NET 4.5 and 4.6. You'll need to add a reference to System.Numerics
BigInteger test = BigInteger.Pow(7, 27) % 55;
So I am looking at a program that downloads map tiles. From here I have got a method for c# for getting a tiles grid coordinates from longitude and latitude points that looks like this:
public PointF WorldToTilePos(double lon, double lat, int zoom)
{
PointF p = new PointF();
p.X = (float)((lon + 180.0) / 360.0 * (1 << zoom));
p.Y = (float)((1.0 - Math.Log(Math.Tan(lat * Math.PI / 180.0) +
1.0 / Math.Cos(lat * Math.PI / 180.0)) / Math.PI) / 2.0 * (1 << zoom));
return p;
}
on the same site it states that the mathematics for working this out are:
where z = zoom.
Now my question is what does the << operator do and what does (1 << zoom) mean. Because as far as I can see the c# method is incorrect and (1 << zoom) should be replaced with Math.Pow(2,zoom); in x and Math.Pow(2,zoom-1) for y.
Its a left shift operator. It is shifting the bits in the number 1 to the left by zoom number of places.
In the context of this 1 << zoom, it is basically creating a power of 2.
If zoom equals 3, then its doing a 2^3:
0000 0001 = 1
After executing 1 << zoom (3)
0000 1000 = 8
As you pointed out, you could replace it with Math.Pow, however, bit operations are much, much faster. Math.Pow has to deal with the problem in its general case, dealing with fractional powers and other issues. Bit operations are natural CPU operations, that execute in a single CPU cycle.
<< is a bit-shifting operator.
Consider the binary number 00001110 (decimal 14). When it's bit-shifted to the left by 1, it becomes 00011100 (decimal 28). The latter, when bit-shifted to the right by 1, becomes 00001110 (decimal 14) again.
Typically, bit-shifting an integer by 1 causes a multiplication by 2 (when shifting to the left) or an integer division by 2 (when shifting to the right).
Bit-shifting by 2 (that is, bit-shifting by 1, two times) causes a multiplication by 2*2 or an integer division by 2*2.
In the general case, bit-shifting a number by N causes multiplication or division by 2^N.
It bitshifts the one to the left zoom number of times. This is effectively the same thing as raising 2 to the zoom power.
For y, it achieves the z-1 by dividing by two
I can write the program
int a = 3;
int b = 4;
Console.WriteLine(a % b);
The answer I get is 3. How does 3 mod 4 = 3???
I can't figure out how this is getting computed this way.
I wasn't quite sure what to expect,
but I couldn't figure out how the
remainder was 3.
So you have 3 cookies, and you want to divide them equally between 4 people.
Because there are more people than cookies, nobody gets a cookie (quotient = 0) and you've got a remainder of 3 cookies for yourself. :)
Because the remainder of 3 / 4 = 3.
http://en.wikipedia.org/wiki/Modulo_operator
3 mod 4 is the remainder when 3 is divided by 4.
In this case, 4 goes into 3 zero times with a remainder of 3.
I found the accepted answer confusing and misleading.
Modulus is NOT the same as modern division that returns a ratio of dividend and divisor. This is often expressed as a decimal quotient that includes the remainder in the quotient. That is what trips people up.
Modulus is just the remainder in division before its used in a decimal quotient.
Example: The division of two numbers is often expressed as a decimal number (quotient). But the result of the division of say, 1/3, can also be expressed in whole numbers as "0 with a remainder of 1". But that form of quotient is not very helpful in modern math, so a decimal value or the ratio of the two numbers is often what we see returned in modern calculators.
1 / 3 = .333333333......
But modulus does not work that way. It ignores the decimal quotient value or ratio returned from division, takes the quotient expression of "0 with a remainder of 1" in 1/3, and extracts the 1 or remainder that was returned from that division. It just strips out the remainder from the quotient and spits back the remainder of division before its converted to a decimal. Below is how modulus works...
1 % 3 = 1
As such, a better way of describing Modulus is to say it is what is left over as an integer (remainder) in the first number (dividend) after dividing the second number (divisor) into it as many times as possible.
1 % 1 = 0 because after dividing 1 into 1, one time, there's nothing left
2 % 1 = 0 because after dividing 1 into 2, two times, there's nothing left
1 % 2 = 1 because 2 won't go into 1, so 1 is left
These whole number remainders returned by modulus (modular math) are useful in software programs in extracting the day of a week, creating alternating sequences, finding if a number is even or odd, etc.
I already think that the user may have understood the answers. Because there are so many good programmer.. in simple wording % tells you the reminder after dividing with your own integer.
e.g.
int a = int.Parse(Console.ReadLine());
int b = a % 2;
Now your input 13, it will give 1, because after diving 13 by 2 remainder is 1 in simple mathematics. Hope you got that.
As explained by others, but if you don't want to use the "mod" operator. Here is the equation to figure out the remainder of "a" divided by "n"
a-(n* int(a/n))
Another "as explained by others", but if you're curious about several more ways to do modulus (or use an alternative method), you can read this article which benchmarks a few different ways.
Basically, the fastest way is the good old fashioned modulus operator, similar to:
if (x % threshold == some_value)
{
//do whatever you need to
}
Perhaps the C# implementation is self explanatory -
static void Main(string[] args)
{
int a = 3;
int b = 4;
Console.WriteLine(a % b);
Console.WriteLine(MOD(a,b));
Console.ReadKey();
}
public static int MOD(int a, int b)
{
int i, j, k;
i = a / b;
j = i * b;
k = a - j;
return k;
}