问题
Today I came a cross this strange behaviour, could someone explain why it happens?
var x = -1U; // When using -1UL it complains though.
Console.WriteLine(x.GetType().Name);
Console.WriteLine(x);
Output:
Int64
-1
MSDN says:
If the literal is suffixed by U or u, it has the first of these types in which its value can be represented: uint, ulong.
https://msdn.microsoft.com/en-us/library/aa664674%28v=vs.71%29.aspx
回答1:
Your confusion stems from you interpreting this as the number -1
, followed by a suffix U
. It's actually the negation -
of the number 1U
. That number 1U
has type uint
, as indicated by the quote in your question. Negating an uint
produces a long
.
回答2:
What you are doing here is using unary operator -
and as per https://msdn.microsoft.com/en-us/library/aa691145(v=vs.71).aspx
For the unary - operator, the operand is converted to type T, where T is the first of int and long that can fully represent all possible values of the operand. The operation is then performed using the precision of type T, and the type of the result is T. The unary - operator cannot be applied to operands of type ulong.
If i do something like
var x =-1UL;
i get a compiler error Operator '-' cannot be applied to operand of type 'ulong
It's because i am using unary operator
Whereas If i do
var x =2UL-1UL;
The compiler doesnt complain because I am now using binary operator
When you do var x=-1UL
the compiler interprets it as var x=0UL-1UL
which if say succeded will produce -1UL
however if you take a look at the range of UL it is 0 and 18446744073709551615
so -1UL
is outside it's range hence the compile time error. same can be done for ushort
as well.
回答3:
On this line of code you ask compiler to choose type by using an implicit type var
, then you assign a negative value to it by using this -
sign :
var x = -1U; // it is converted to simple -1
So it's converted by compiler to -1
and it finds closest type with range corresponding to uint
s range and which can work with negative values - long
Console.WriteLine(x.GetType().Name); // displays long (Int64)
Console.WriteLine(x); // displays -1
As been said you can use unchecked
keyword to let compile know that it should not perform overflow-checking . A quote from MSDN :
The unchecked keyword is used to suppress overflow-checking for integral-type arithmetic operations and conversions.
So this should compile and run and x will be of type ulong
:
// UInt64 here
var x = unchecked((ulong)-1);
来源:https://stackoverflow.com/questions/32859555/unsigned-integer-literal-having-negative-sign