开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜