% Operator (C# Reference)
Visual Studio 2010
The % operator computes the remainder after dividing its first operand by its second. All numeric types have predefined remainder operators.
User-defined types can overload the % operator (see operator). When a binary operator is overloaded, the corresponding assignment operator, if any, is also implicitly overloaded.
Really a remainder operator
See http://blogs.msdn.com/b/ericlippert/archive/2011/12/05/what-s-the-difference-remainder-vs-modulus.aspx.
Particulary paraghaph Nine:
However, that is not at all what the % operator actually does in C#. The % operator is not the canonical modulus operator, it is the remainder operator. The A % B operator actually answer the question "If I divided A by B using integer arithmetic, what would the remainder be?" - Eric Lippert
Edit by SJ at MSFT: This has already been changed in the topic (thanks to Eric). The updated version should be on msdn soon. Thanks.
Particulary paraghaph Nine:
However, that is not at all what the % operator actually does in C#. The % operator is not the canonical modulus operator, it is the remainder operator. The A % B operator actually answer the question "If I divided A by B using integer arithmetic, what would the remainder be?" - Eric Lippert
Edit by SJ at MSFT: This has already been changed in the topic (thanks to Eric). The updated version should be on msdn soon. Thanks.
- 12/8/2011
- fatoms
- 1/6/2012
- SJ at MSFT
Avoid modulus operator with types float and double.
This is an example of using the C# modulus operator with the types int, decimal, float, and double.
Note the error for the types float and double.
int int int
x divisor rem
-10 2 0
-9 2 -1
-8 2 0
-7 2 -1
-6 2 0
-5 2 -1
-4 2 0
-3 2 -1
-2 2 0
-1 2 -1
0 2 0
1 2 1
2 2 0
3 2 1
4 2 0
5 2 1
6 2 0
7 2 1
8 2 0
9 2 1
10 2 0
decimal decimal decimal
x divisor rem
-1 0.2 0.0
-0.9 0.2 -0.1
-0.8 0.2 0.0
-0.7 0.2 -0.1
-0.6 0.2 0.0
-0.5 0.2 -0.1
-0.4 0.2 0.0
-0.3 0.2 -0.1
-0.2 0.2 0.0
-0.1 0.2 -0.1
0 0.2 0
0.1 0.2 0.1
0.2 0.2 0.0
0.3 0.2 0.1
0.4 0.2 0.0
0.5 0.2 0.1
0.6 0.2 0.0
0.7 0.2 0.1
0.8 0.2 0.0
0.9 0.2 0.1
1 0.2 0.0
double double double double
x divisor rem error
-1 0.2 -0.2 0.2
-0.9 0.2 -0.1 2.77555756156289E-17
-0.8 0.2 0 0
-0.7 0.2 -0.0999999999999999 8.32667268468867E-17
-0.6 0.2 -0.2 0.2
-0.5 0.2 -0.1 2.77555756156289E-17
-0.4 0.2 0 0
-0.3 0.2 -0.1 2.77555756156289E-17
-0.2 0.2 0 0
-0.1 0.2 -0.1 0
0 0.2 0 0
0.1 0.2 0.1 0
0.2 0.2 0 0
0.3 0.2 0.1 2.77555756156289E-17
0.4 0.2 0 0
0.5 0.2 0.1 2.77555756156289E-17
0.6 0.2 0.2 0.2
0.7 0.2 0.0999999999999999 8.32667268468867E-17
0.8 0.2 0 0
0.9 0.2 0.1 2.77555756156289E-17
1 0.2 0.2 0.2
float float float float
x divisor rem error
-1 0.2 -0.2 0.2
-0.9 0.2 -0.09999996 3.72529E-08
-0.8 0.2 0 0
-0.7 0.2 -0.09999998 2.235174E-08
-0.6 0.2 -1.490116E-08 1.490116E-08
-0.5 0.2 -0.09999999 7.450581E-09
-0.4 0.2 0 0
-0.3 0.2 -0.1 7.450581E-09
-0.2 0.2 0 0
-0.1 0.2 -0.1 0
0 0.2 0 0
0.1 0.2 0.1 0
0.2 0.2 0 0
0.3 0.2 0.1 7.450581E-09
0.4 0.2 0 0
0.5 0.2 0.09999999 7.450581E-09
0.6 0.2 1.490116E-08 1.490116E-08
0.7 0.2 0.09999998 2.235174E-08
0.8 0.2 0 0
0.9 0.2 0.09999996 3.72529E-08
1 0.2 0.2 0.2
private static void ModulusErrors()
{
string format = "{0,4} {1,7} {2,3} {3,7} {4,7} {5,7} {6,7} {7,7} {8,22} {9,22} {10,7} {11,7} {12,22} {13,22}";
Console.WriteLine(format, "int", "int", "int", "decimal", "decimal", "decimal", "double", "double", "double", "double", "float", "float", "float", "float");
Console.WriteLine(format, "x", "divisor", "rem", "x", "divisor", "rem", "x", "divisor", "rem", "error", "x", "divisor", "rem", "error");
for (int i = -10; i <= 10; i++)
{
int intX = i;
int intDivisor = 2;
int intRem = intX % intDivisor;
decimal deciamlX = (decimal)(i / 10.0);
decimal decimalDivisor = (decimal)0.2;
decimal decimalRem = deciamlX % decimalDivisor;
double doubleX = (double)i / 10.0;
double doubleDivisor = (double)0.2;
double doubleRem = doubleX % doubleDivisor;
double doubleError = (double)decimalRem - doubleRem;
if (doubleError < 0)
{
doubleError = doubleError * -1;
}
float floatX = (float)(i / 10.0);
float floatDivisor = (float)0.2;
float floatRem = floatX % floatDivisor;
float floatError = (float)decimalRem - floatRem;
if (floatError < 0)
{
floatError = floatError * -1;
}
Console.WriteLine(format, intX, intDivisor, intRem, deciamlX, decimalDivisor, decimalRem, doubleX, doubleDivisor, doubleRem, doubleError, floatX, floatDivisor, floatRem, floatError);
}
}