Addition in C#.net doesn't work in some cases [duplicate]

  • A+
Category:Languages

This question already has an answer here:

i have following case

beleg.PreisDB = (double?)orders.Where(x => x.orderId == beleg.auftrnr).Sum(x => x.itemPrice + x.shippingPrice + x.giftWrapPrice) ?? 0; beleg.PreisCouponDB = (double?)orders.Where(x => x.orderId == beleg.auftrnr).Sum(x => x.itemPromotionDiscount + x.shipPromotionDiscount) ?? 0; var gesamtPreis = Math.Round(beleg.PreisDB??0 + beleg.PreisCouponDB??0, 2); 

I have added a quickwatch in debug to some fields in my case:

beleg.PreisDB == 8.39 beleg.PreisDB??0 == 8.39 beleg.PreisCouponDB == -0.49 beleg.PreisCouponDB??0 == -0.49 

And now the strange behaviour also from quickwatch and of course the result

beleg.PreisDB??0 + beleg.PreisCouponDB??0 == 8.39 Math.Round(beleg.PreisDB??0 + beleg.PreisCouponDB??0, 2) == 8.39 gesamtPreis == 8.39 

So the addition of 8.39 + -0.49 doesn't give me 7.9 but 8.39 This code was running for 600k cases on at least two i had this behaviour the others behaved well. I'm to blind to see my error at the moment. The question is why is .net behaving like this? I'm Using Visual Studio 2015 with .net 4.5.2.

 


The problem is precedence - + has higher precedence than ??, so it "binds tighter".

Here's a complete example to demonstrate:

using System;  class Test {     static void Main()     {         double? x = 8.39;         double? y = -0.49;          // Your expression         Console.WriteLine(x ?? 0 + y ?? 0);          // The equivalent you're expecting         Console.WriteLine((x ?? 0) + (y ?? 0));          // The actual bracketing         Console.WriteLine(x ?? ((0 + y) ?? 0));     } } 

Another alternative would be to use Nullable<T>.GetValueOrDefault() instead of ?? 0:

Console.WriteLine(x.GetValueOrDefault() + y.GetValueOrDefault()); 

But I think I'd probably just use the version with brackets - so in your case:

var gesamtPreis = Math.Round((beleg.PreisDB ?? 0) + (beleg.PreisCouponDB ?? 0), 2); 

I would definitely put the spaces in round ?? just like most other operators, as otherwise it's giving you the impression of binding very tightly (like the . operator does).

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: