Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Impossible comparison between ulong and long suddenly possible

I know why this is not allowed:

ulong x = 0xFEDCBA9876543210;
long y = Int64.MaxValue;
Console.WriteLine(x < y);

Obviously, there is no way for the runtime to implicitly cast either operand to the other type or a larger type to make the comparison work.

Operator '<' cannot be applied to operands of type 'ulong' and 'long'.

So, this is also not allowed (with MinValue and const):

ulong x = 0xFEDCBA9876543210;
const long y = Int64.MinValue;
Console.WriteLine(x < y);

Yet, this is allowed (with MaxValue instead):

ulong x = 0xFEDCBA9876543210;
const long y = Int64.MaxValue;
Console.WriteLine(x < y);

There is no overload of < accepting a ulong and long, but I saw with Reflector that this will silently convert Int64.MaxValue to a ulong. But this does not always happen. How does it work, and what considerations are the reason for this inconsistency?

like image 532
Daniel A.A. Pelsmaeker Avatar asked Jul 26 '12 23:07

Daniel A.A. Pelsmaeker


People also ask

What is long and Ulong?

A long value is stored in 64-bit,with its first digit to show if it's a positive/negative number. while ulong is also 64-bit, with all 64 bit to store the number. so the maximum of ulong is 2(64)-1, while long is 2(63)-1.

What is a Ulong?

ulong is a keyword that is used to declare a variable which can store an unsigned integer value from the range 0 to 18,446,744,073,709,551,615. It is an alias of System. UInt64. ulong keyword occupies 8 bytes (64 bits) space in the memory.

What is Unint?

A UINT is a 32-bit unsigned integer (range: 0 through 4294967295 decimal).

What's the difference between INT and UINT?

uint means “unsigned integer” while int means “signed integer”. Unsigned integers only contain positive numbers (or zero). In addition there two alias types: byte which is the same as uint8 and rune which is the same as int32 .


2 Answers

One big difference between long y = Int64.MaxValue; if (x < y)... and if (x < Int64.MaxValue) is that in the latter case the compiler can actually see the constant value if it desired to. It can see that the actual constant value fits in the ulong range and therefore an implicit cast is ok.

For a plain variable long y, the compiler can't make any assumptions about what the runtime value of y is. Nevermind that the assignment statement is just one statement up; the compiler doesn't keep track of values assigned to variables.

As noted by DarkGray, a const var behaves as a constant since you have told the compiler that its value will never change.

like image 165
dthorpe Avatar answered Nov 09 '22 07:11

dthorpe


Const long with value in ulong range silently converts to const ulong.

This is allowed:

ulong x = 0xFEDCBA9876543210; 
const long y = Int64.MaxValue; 
Console.WriteLine(x < y); 

const ulong z = y;
like image 38
Serj-Tm Avatar answered Nov 09 '22 05:11

Serj-Tm