I have a class which represents a shape. The Shape class has a property called Angle. I want the setter for this property to automatically wrap the value into the range [0,359].
Unfortunately, a simple _Angle = value % 360;
only works for positive numbers. In C#, -40 % 360 == -40
. Google calc does it the way I want it. The value should be 320.
What's the most elegant solution in C#?
Here's the best way I've got so far:
public double Angle {
get { return _Angle; }
set {
if ( value >= 0 ) {
_Angle = value % 360;
}
else {
_Angle = value - (360 * ((int)(value / 360) - 1));
}
}
}
Edit:
Thanks guys, I now have:
public double Angle {
get { return _Angle; }
set {
_Angle = (value % 360) + ((value < 0) ? 360 : 0);
}
}
..Which is a lot better :)
Although this is for Java, Java also has the same behavior for modulus. (i.e. -40 % 360 == -40
).
The below code should return an answer from [0. 360), regardless of the given angle, positive or negative.
public class Mod
{
public static int mod(int a, int b)
{
if (a < 0)
return b + (a % b);
else
return a % b;
}
public static void main(String[] args)
{
System.out.println(mod(40, 360)); // 40
System.out.println(mod(-40, 360)); // 320
System.out.println(mod(-400, 360)); // 320
}
}
Note that works when the given angle is past -360.
While your solution works for the problem you have the algorithm is actually not identical to the one used by Google. It differs if you use a negative divisor.
public double GoogleModulo(double value, double divisor)
{
long q = (long)Math.Floor(value / divisor);
return value - q * divisor;
}
Console.WriteLine(GoogleModulo( 40, 360)); // 40
Console.WriteLine(GoogleModulo( -40, 360)); // 320
Console.WriteLine(GoogleModulo(-400, 360)); // 320
Console.WriteLine(GoogleModulo( 40, -360)); // -320
Check google's response to the last calculation here.
The algorithm is explained on wikipedia and attributed to Donald Knuth.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With