Search code examples
c#doubleoverflowintprimitive

.NET primitive type addition oddities?


I was curious, so I ran a couple of tests to see how .NET handles overflow (I couldn't find it documented anywhere). I'd almost wish they spit out overflow errors instead of the results because honestly these results are just bizarre:

  1. Int32.MaxValue + Int32.MaxValue = -2
    I understand that it wraps around, but why do that instead of throwing an OverflowException? Isn't that what "unchecked" is for... to ignore overflows? I'm kind of baffled as to what unchecked is for now, especially since I've seen it used for creating hash values.

  2. Double.PositiveInfinity + Double.NegativeInfinity = Double.NaN
    Another oddity. 1 + -1 = 0. 100 + -100 = 0. So why is Infinity + -Infinity = NaN?

  3. Double.PositiveInfinity / Double.PositiveInfinity = Double.NaN
    Again, why the oddity? I'd figure this should be 1 or possibly 0 (b/c the limit of x / Infinity = 0). In fact... Double.MaxValue / Double.PositiveInfinity = 0 ...

  4. Double.PositiveInfinity / 0 = Infinity
    What!? No DivideByZeroException!?

  5. Double.MaxValue + Double.MaxValue = Infinity
    Yea, this one does not throw an OverflowException, but also does NOT wrap around? So I guess not all primitive types behave like int does. Oddly enough, I can do things such as Double.MaxValue + 1 = 1.79769313486232E+308. So adding beyond the MaxValue of a double is possible (probably loses precision?), but after some unknown number (it can probably be figured out - or has already) it loses its ability to display a valid number and gives back Infininty?

Well, the rest is kind of repetitive. I'm just wondering why these operate the way they do? Especially the Double operators. It was very unexpected for me to be able to add beyond the MaxValue.


Solution

    1. Yes; checked will fix that; unchecked is the default behaviour
    2. Mathematically, you can't add +inf and -inf, and you can't infer a sign. NaN is the only sane option; however, +inf + +inf => +inf, and -inf + -inf => -inf, like you might deduce
    3. Again, mathematically that first work. Not least, it would lead to 2*x/x=>1, which would be worse. But basically : inf is not a number
    4. No, they don't; that is the expected behaviour for floating point
    5. Float doesn't wrap; exceeding max is infinity