0

I'm currently creating a unit test for a method.

The convert method this is supposed to test basically consists of return if value > 0 so I had the idea to check unsigned overflows as well.

While creating test cases for the test I stumbled upon this very peculiar behavior of the U and UL suffixes.

[DataTestMethod]
// more data rows
[DataRow(-1U, true)] // Technically compiles, but not to what I expected or "wanted"
[DataRow(-1UL, true)] // "CS0023: Operator '-' cannot be applied to operand of type 'ulong'"
// more data rows
public void TestConvertToBool(object value, bool result)
{
    // For testing purposes
    ulong uLong = -1UL; // "CS0023: Operator '-' cannot be applied to operand of type 'ulong'"
    uint uInt = -1U; // "CS0266: Cannot implicitly convert type 'long' to 'uint'. An explicit conversion exists (are you missing a cast?) - Cannot convert source type 'long' to target type 'uint'"
    var foo = -1U; // foo is of type 'long'
    var bar = 1U; // bar is of type 'uint'

    // ... do the actual assertion here
}

Why do they behave this way? Shouldn't it just overflow to the max values of uint and ulong?

I couldn't find any answer to this. The reference source seems to only contain the wrapper objects UInt32 and such that don't include any operators.

Note: I'm aware that there is no real point in doing this in the first place. I just found the behavior to be very unexpected.

IDarkCoder
  • 709
  • 7
  • 18
  • 1
    `U` stands for unsigned, defining negative `unsigned` doesn't make sense. You can convert negative signed to unsigned though, which is [useful](https://stackoverflow.com/q/33243440/1997232). – Sinatr Sep 18 '20 at 11:36
  • @Sinatr like I said, I'm aware that it doesn't make sense. I'm just curious about why it behaves the way it does. I also know what unsigned means, that's why I said `Shouldn't it just overflow to the max values of uint and ulong?` – IDarkCoder Sep 18 '20 at 11:38
  • 1
    Making it overflow makes sense if you know how the numbers look if they're implemented as 2s complement numbers. From a language design perspective that could be considered an implementation detail that you shouldn't expose to the programmer. – Hans Kilian Sep 18 '20 at 12:22

1 Answers1

2

It seems that it's converting the uint to a long so that there are always enough bits to store the entire potential range of resulting positive and negative values. The - operator can't be applied to a ulong because there's no larger type to convert it to

Tharwen
  • 3,057
  • 2
  • 24
  • 36