Elegant way to negate a numeric value based on a boolean value
I have a decimal variable that I would like to negate if a boolean variable is true. Can anyone think of a more elegant way to do it than this:
decimal amount = 500m;
bool 开发者_如何转开发negate = true;
amount *= (negate ? -1 : 1);
I'm thinking something along the lines of bitwise operators or a strictly mathematical implementation.
Personally, I would just use an if statement, since I feel that it's the most clear in terms of intent:
decimal amount = 500m;
bool negate = true;
// ...
if (negate)
amount *= -1;
This is really not any extra typing (it's actually shorter!), and more clear in my opinion.
Use the decimal unary negation operator (as you are sort of already doing):
using System;
class Program
{
static void Main()
{
bool negate = true;
decimal test = 500M;
Console.WriteLine(negate == true ? -test : test);
}
}
Output:
-500
Frankly, this is much clearer and better than multiplying by -1 in that strange way.
Another shot across the math wizards?
How about adjusting your existing solution to be slightly more readable, but still make use of the statement?true:false shortcut?
Your solution was:
amount *= (negate ? -1 : 1);
Maybe refactor that to
amount = (negate ? amount*-1 : amount);
To add even more readability to your code, you might make a reusable class that handles that kind of stuff for you:
public static class MathHelpers()
{
// Negates the result if shouldNegate is true, otherwise returns the same result
public static decimal Negate(decimal value, bool shouldNegate)
{
// In this black-box solution you can use "fancier" shortcuts
return value *= negate ? -1 : 1;
}
}
And in your other code, you now have a very readable function to use...
decimal amount = 500m;
bool negate = true;
amount = MathHelper.Negate(amount, negate);
All in all, though I agree that elegance and readability live in the same cart, not different ones:
if (condition)
output *= -1;
is more readable than
value *= condition ? -1 : 1;
public static decimal Negate(this decimal value, bool isNegate){
if(isNegate) return value * -1;
return value;
}
Make extension method on decimal. Easy to use.
call like amount.Negate(negate)
This already exists, since Framework 1.1:
System.Decimal.Negate method
public static decimal Negate( decimal d )
Sample Usage:
decimal amount = 500m;
bool negate = true;
if(negate)
amount = decimal.Negate(amount);
// amount now holds -500
// Use amount
If your negate
flag is based on some numeric value you can use Math.Sign
, that's the most "mathematical" way I can think of.
double negationValue = -45.0;
amount *= Math.Sign(negationValue);
or in boolean case just (not really elegant):
amount *= Math.Sign(0.5 - Convert.ToByte(negate));
amount *= Math.Pow(-1, Convert.ToInt32(negate))
This is under the assumption that typecasting a boolean in C# will yield a 0 on false, and a 1 for true. I however don't think this is elegant as it is an obfuscation.
edit: converted to an int
精彩评论