Question

I was reading How can one simplify network byte-order conversion from a BinaryReader? and the initial code in the question made me think about the capabilities of the explicit cast between UInt32 and Int32. My main concern is with values greater than Int32.MaxValue or less than 0.

These casts should be equivalent, but one works and the other causes an error:

public static void TestConverstion()
{
    // runs just fine, CastBack == aUInt
    UInt32 aUInt = UInt32.MaxValue; // 4294967295
    Int32 anInt = (Int32)aUInt; // -1
    UInt32 castBack = (UInt32)aUInt; // 4294967295

    // Build Error: Constant value '4294967295' cannot be converted to a 'int' (use 'unchecked' syntax to override) 
    UInt32 oneLineCastBack = (UInt32)(Int32)UInt32.MaxValue;
}

Why is one valid and not the other?

Where is the behavior of this cast documented? The best documentation I could find was Explicit Numeric Conversions Table (C# Reference), which acknowledges that there is an explicit cast, but warns that explicit casts "may cause loss of precision or result in throwing exceptions". Experimentation says that no exception is thrown, nor is precision lost.

UInt32 Structure suggests that since UInt32 is not part of the Common Language Specification that you should just use an Int64 and waste half the bits when you need to represent a value above Int32.MaxValue but below UInt32.MaxValue.

No correct solution

OTHER TIPS

The way you have the code laid out, you are simply dealing with the compiler's ability to determine the potential outcome. Nothing really changes. As the error message suggests to you, you could do this and arrive at the exact same result:

unchecked { UInt32 oneLineCastBack = (UInt32)(Int32)UInt32.MaxValue; }

The only difference between the two examples you give is that the second one is a direct cast of the const value to Int32 which the compiler can immediately recognize as an error.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top