Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.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.

like image 249
michael Avatar asked May 22 '26 14:05

michael


2 Answers

  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
like image 87
Marc Gravell Avatar answered May 25 '26 03:05

Marc Gravell


About 2/3

Infinity isn't a number. It doesn't act like a number, either.

If we let a be the number of positive integers (1, 2, 3, ...), b be the number of even integers (2, 4, 6, ...), and c be the number of odd integers (1, 3, 5, ...). It's pretty clear that both a, b and c are infinity.

You would probably expect that a - a = 0, which means in this case infinity - infinity = 0. However, you could also expect a - b = c, since c are the numbers in a, which are not in b. This, however, gives us that infinity - infinity = infinity.

By constructing your infinities correctly, you could produce any integer as the answer for infinity - infinity. Therefore, it makes no sense to give it a proper definition, so we let it be NaN, or "Not a Number".

The same goes for division, which is point 3.

like image 32
Sebastian Paaske Tørholm Avatar answered May 25 '26 03:05

Sebastian Paaske Tørholm



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!