Weird behavior of -1U and -1UL

261 Views Asked by At

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.

1

There are 1 best solutions below

0
On BEST ANSWER

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