Why does the % operator sometimes output positive and sometimes negative? - c#

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.

Related

Math function to remove minus

If input value is -0.088 and I want take from x = 0.8 like this 0.8 - -0.088 but in result I want get 0.712 instead of 0.888 as it would be with minus 0.8 - 0.088.
How to remove minus from number without direct string processing, can I use some Math function for such case:
double x1 = 0.8;
double x2 = 0.8;
double a = -0.088;
double b = 0.088;
x1 = (x1 - a);
x2 = (x2 - b);
Console.WriteLine("0.8 minus -0.088 equals to [ " + x1 +
" ]\r\n0.8 minus 0.088 equals to [ " + x2 + " ]");
result:
0.8 minus -0.088 equals to [ 0.888 ]
0.8 minus 0.088 equals to [ 0.712 ]
desired result:
0.8 minus -0.088 equals to [ 0.712 ]
0.8 minus 0.088 equals to [ 0.712 ]
Removing minus corresponds to the mathematical concept of absolute value. .NET implementation of this function is Math.Abs method:
x1 = (x1 - Math.Abs(a));
It is mathematically correct, though. Doing 0.8 - -0.088, will result to 0.8 + 0.088. Try using Math.Abs before subtracting them. Refer to this: https://www.dotnetperls.com/math-abs
x1 = (x1 - Math.Abs(a));
x2 = (x2 - Math.Abs(b));
This should return your desired result.
Hope it helps!
Or you could try to remember some MATHS from junior school and if you know you have a minus figure just multiply it by -1 to turn it positive or if you have a positive no multiply it by -1 to get a negative number.
In this example after we have converted the -8 into a positive 8 with *-1 the 2nd sum (z = y - x) actually adds the numbers together due to the double minus symbols next to each other and returns 18 as a - -b reverses the action to make a + b. LOL I can't believe I can remember simple algebra but not ABS!!
int x = -8;
int y = 10;
int z = y - (x *-1);
Console.WriteLine(z); // z = 10 - 8 = 2
z = y - x;
Console.WriteLine(z); // z = 10 - -8 = 18
Then again I use it all the time in my betting math my BOT uses so that's maybe why I remembered it!
Obviously ABS is simpler but as I was doing just this sum when I came across the page I thought I would waste time writing an answer.

How does modulus differ in C# vs. Excel?

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

Double divided by 1

I guess this is more of a math question, but how come when you divide a double by 1 it returns the decimal points too?
For example, 123.23 % 1 is equal to 0.23.
Shouldn't it return only 0?
MSDN reference says that module does this ex - (x / y) * y where x is the dividend and why is the divider and if you calculate it like that it should return 0.
So tell me how come does it return the decimal points too?
You are not simply dividing by 1, you are taking the modulus. The modulus returns the remainder from the division of the first argument with the second.
This means it subtracts the highest complete divider from the input and returns the remainder. In your case that would be
123.23 - 123 = 0.23
since 123 can be divided by 1 without "anything left". What's left is then the 0.23 you experience.
The modulus operator is handy in many situations. Two very common ones are:
Checking for Even/Odd numbers
If you have an integer number and take the modulo 2 the result is 1 for odd and 0 for even numbers.
Checking for the nth iteration
If you have a loop and say you want to print a result every 10th iteration you could have a continous counter and use code like
if (Counter % 10 == 0) then {
Console.WriteLine("Tick Tock");
}
See MSDN for further examples: https://msdn.microsoft.com/de-de/library/0w4e0fzs.aspx?f=255&MSPPError=-2147217396

Why result of % operator for double differ from decimal? [duplicate]

Consider this:
double x,y;
x =120.0;
y = 0.05;
double z= x % y;
I tried this and expected the result to be 0, but it came out 0.04933333.
However,
x =120.0;
y = 0.5;
double z= x % y;
did indeed gave the correct result of 0.
What is happening here?
I tried Math.IEEERemainder(double, double) but it's not returning 0 either. What is going on here?
Also, as an aside, what is the most appropriate way to find remainder in C#?
Because of its storage format, doubles cannot store every values exactly as is is entered or displayed. The human representation of numbers is usually in decimal format, while doubles are based on the dual system.
In a double, 120 is stored precisely because it's an integer value. But 0.05 is not. The double is approximated to the closest number to 0.05 it can represent. 0.5 is a power of 2 (1/2), so it can be stored precisely and you don't get a rounding error.
To have all numbers exactly the same way you enter / display it in the decimal system, use decimal instead.
decimal x, y;
x = 120.0M;
y = 0.05M;
decimal z = x % y; // z is 0
You could do something like:
double a, b, r;
a = 120;
b = .05;
r = a - Math.floor(a / b) * b;
This should help ;)
I believe if you tried the same with decimal it would work properly.
http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems can help you understand why you get these "strange" results. There's a particular precision that floating point numbers can have. Just try these queries and have a look at the results:
0.5 in base 2
0.05 in base 2
Modulus should only be used with integer. The remainder come from an euclidean division. With double, you can have unexpected results.
See this article
This is what we use.. :)
public double ModuloOf(double v1, double v2)
{
var mult = 0;
//find number of decimals
while (v2 % 1 > 0)
{
mult++;
v2 = v2 * 10;
}
v1 = v1 * Math.Pow(10, mult);
var rem = v1 % v2;
return rem / Math.Pow(10, mult);
}

Learning C#, Math equation not resulting as expected

Learning C#, Math equation not resulting as expected.
This is apart of my homework. I do not understand why the result are not coming out as them should..
First equation
m=2
n=1
int sideA = (m^2) - (n^2);
result -3
Second equation
x1=2
x2=7
float Xmid = (x1 + x2)/2;
result 4
This is because in C# ^ means XOR, not "raised to the power of". To square a number, use
Math.Pow(x, 2)
or simply
x * x
Also dividing integers truncates the fractional part. Use decimal, double, or float to get 3.5 as the midpoint of 3 and 4:
float x1=2
float x2=7
float Xmid = (x1 + x2)/2;
Your first line of code:
int sideA = (m^2) - (n^2);
Is basically m XOR 2 minus n XOR 2. XOR is a bitwise operator that results in the bits where one is true but not both. For more information on the exclusive OR operator, consult Wikipedia. If you're trying to raise m to the power of 2, try something like:
int sideA = Math.Pow(m, 2) - Math.Pow(n, 2);
Your second line of code:
float Xmid = (x1 + x2)/2;
Is (2 + 7) which is 9, divided by the integer 2 which is 4.5, however because dividing an integer by another integer will always result in an integer, only the integer portion of the result will be kept. The fact that you're assigning this expression to a float is irrelevant.
You might want to try:
float Xmid = (x1 + x2)/2.0;
or:
float Xmid = (x1 + x2)/2f;
or declare x1 and x2 as floats, both which will yield 4.5.

Categories