2016-05-02 12 views
2

Почему для этого случая возникает ошибка компиляции: Constant value '-2147483648' cannot be converted to a 'ulong', и я должен использовать unchecked (...) для этого случая?Почему я не могу назначить (1 << 31) ulong var? (Ошибка 25 Постоянное значение ... невозможно преобразовать ...)

ulong xDummy30 = (1 << 30); // works 
ulong xDummy31 = (1 << 31); // ERROR 25 Constant value '-2147483648' cannot be converted to a 'ulong' 
ulong xDummy32 = (1 << 32); // works 

Используя это вместо работы:

ulong xDummy31a = unchecked((ulong)(1 << 31)); 
// or 
ulong xDummy31b = (1ul << 31); // comment from Regis Portalez 
+3

1 << 31 может быть оценено с помощью операндов int32. Можете ли вы оценить 1л << 31? –

+0

Работы @RegisPortalez (например, непроверенная (...) версия). Есть ли причина для этого? – boboes

+0

@boboes это просто способ по умолчанию, когда C# обрабатывает простые числа. –

ответ

5

Согласно MSDN ulong reference всем вашим целочисленным литералам 1 , 30, 31 рассматриваются как INT:

When an integer literal has no suffix, its type is the first of these types in which its value can be represented: int, uint, long,

Согласно MSDN << operator результатом операции < < также внутр. Когда yo сдвиг на 30, результат положительный, при сдвиге на 31 результат - отрицательный int, который не может быть назначен ulong.

Редактировать: HVD указал мне ошибку в следующем. Спасибо, HVD!

Start Error - При переключении 32 бита, компилятор знает, что вы хотите, ULONG, и, таким образом, результат операции сдвига является положительным длинным, который может быть преобразован в unlong - конец ошибка

правильная причина, почему 1 < < 32 не приводит к ошибке компиляции в предоставленной ссылке для оператора < <:

If the first operand is an int, the shift count is given by the low-order five bits of the second operand. That is, the actual shift count is 0 to 31 bits.

32 в двоичную: 0010 0000; нижний порядок пять бит: 0 0000, поэтому фактический выполненный сдвиг равен 1 < < 0, что приводит к int со значением 1, которое, конечно, может быть присвоено ulong.

Чтобы решить эту проблему, убедитесь, что номер 1 длинный. В этом случае 1 < < 31 остается положительным долго.

You can also use suffixes to specify the type of the literal according to the following rules: If you use L, the type of the literal integer will be either long or ulong according to its size.

Таким образом, 1L является длинным; 1L < < 31 является положительным длинным и, следовательно, может быть присвоено ulong

+1

«При переключении 32 бит компилятор знает, что вы хотите улуг» - Э? Это не так, как это работает. '1 << 32' имеет тип' int' и значение '1', как требуется спецификацией языка C#, которая определяет, что используются только нижние 5 бит счетчика, если LHS имеет тип' int' или ' uint'. Это также упоминается в документации, на которую вы ссылаетесь. – hvd

0
var a = (1<<31); 
    Console.WriteLine(a); 

    ulong num = unchecked((ulong)(1<<31)); 
    Console.WriteLine(num); 

Output: 
-2147483648 
18446744071562067968 
< 31 значение не может поместиться в uint6

https://dotnetfiddle.net/Widget/TfjnSZ

+0

Диапазон улонг составляет от 0 до 18 446 744 073 709 551 645 – Reddy

+0

Почему 2^31 не может вписаться в 'UInt64'? Диапазон 'UInt64' равен' [0, 2^64-1] '. Вам просто нужно использовать правильные типы данных. 'var e = 1L << 62;' работает отлично. – derpirscher

 Смежные вопросы

  • Нет связанных вопросов^_^