views:

131

answers:

4

Are there any differences between decimal.Negate(myDecimal) and myDecimal * -1 (except maybe readability)?

A: 

From MSDN, decimal.Negate:

Returns the result of multiplying the specified Decimal value by negative one.

No practical difference then, though readability is important.

Oded
This however does not explain the implementation. Is the IL code the same?Also, what is the purpose of having it as a separate method?
anchandra
@anchandra - readability is a good reason. I did not look into the IL, but wouldn't be surprised if it was the same.
Oded
@Oded That is why I asked the question. I "guess" they are the same, but I would like a confirmation
anchandra
Reflector shows the code for Negate as: `return new decimal(d.lo, d.mid, d.hi, d.flags ^ -2147483648);`. I doubt that's the same IL generated for `myDecimal * -1` or `-myDecimal`.
Jonathan
Also, remember that just because the IL is the same (or different) doesn't mean it will be in the future (even in the next security patch). Implementation being subject to change and all.
Jonathan
@Jonathan. Good point. I am interested in other things i should consider though. The IL code was an example of differences to have in mind between the 2 approaches
anchandra
+2  A: 

Personally, I find -myDecimal to be more readable than either (I'm no math geek, but I pretty sure all three are equivalent), but then again, I generally prefer compact notation.

If that is out, I'd go with Negate since I like to avoid magic numbers floating around in my code, and while the -1 as used there isn't really a magic number, it sure looks like one at first glance.

Jonathan
+11  A: 

I suspect Negate exists because there's a unary minus operator (op_UnaryNegation), and it's good practice to have methods representing the equivalent functionality so that languages which don't support operator overloading can still achieve the same result.

So instead of comparing it with myDecimal * -1 it may be helpful to think of it as being an alternative way of writing -myDecimal.

(I believe it's also optimised - given the way floating point works, negating a value is much simpler than normal multiplication; there's just a bit to flip. No need to perform any actual arithmetic.)

Jon Skeet
+4  A: 

If you look in the .NET source with .NET Reflector, you will see the following: (getting coffee until it finally opens..)

public static decimal Negate(decimal d)
{
    return new decimal(d.lo, d.mid, d.hi, d.flags ^ -2147483648);
}

Looks like this is a fancy way to say -1 due to the way decimal internally works.

If you do *-1 it maps it to the following call:

FCallMultiply(ref result, yourNumber, -1M);

which will likely produce different IL code.

atamanroman