开发者

.NET primitive type addition oddities?

开发者 https://www.devze.com 2023-03-20 14:34 出处:网络
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 hone

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 precisio开发者_如何学Gon?), 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.


  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


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.

0

精彩评论

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

关注公众号