2008-10-26 2 views
12

Когда вы пытаетесь объявить переменную unsigned в C# .NET со значением вне ее диапазона значений, она помечена как ошибка компилятора, но если вы производите отрицательное значение во время выполнения и назначаете его этому переменная во время выполнения обертывает значение.Разница двух 'uint'

uint z = -1; // Will not compile 

uint a = 5; 
uint b = 6; 
uint c = a - b; // Will result in uint.MaxValue 

Есть ли веская причина, почему переменные без знака обертываются в такой ситуации, а не бросают исключение?

Спасибо.

+0

То же касается для улонга – Llyle 2008-10-26 21:29:31

ответ

26

Объявление непринятой переменной в C# не помечено ошибкой - попытка присвоить недопустимое значение переменной. Например, вот переменная, которая определенно не назначена (если это локальная) после объявления:

uint z; 

-1 не является допустимым значением для UINT больше, чем 0,5 является, поэтому ваш пример Wouldn Компиляция.

Теперь, как и для остальных: целые числа просто обертываются при переполнении - так же, как добавление 1 к int.MaxValue возвращает int.MinValue. Это значительное улучшение производительности за счет того, что программа проверяет каждую операцию на переполнение - за счет потенциально не обнаруживающей ошибки.

Это только если вы находитесь в неконтролируемом контексте, заметьте - если вы выполняете любую из этих операций в проверенном контексте, вместо этого вы получите исключение. Например;

class Test 
{ 
    static void Main() 
    { 
     checked 
     { 
      uint a = 5; 
      uint b = 6; 
      uint c = a - b; 
     } 
    } 
} 

Run, что и вы увидите OverflowException вышвырнут. Если это то, что вы хотите для всего проекта, вы можете установить его в свойствах проекта (или скомпилировать с опцией командной строки /checked+ до csc.)

EDIT: Стоит отметить, что другие ответы показали, что вы можете поставить меньшее количество кода в проверяемом контексте - просто объявление и присвоение c или даже просто расчет. Все это довольно гибко.

+0

Darm - надел на него ... Я попал в «Пост», чтобы найти, что у вас уже есть +5 ... [delete ...] – 2008-10-26 21:38:48

+0

Это быстрый набор голосов. Это не похоже на то, что он сидит некоторое время ... – 2008-10-26 21:39:36

+1

Удивительно, но я никогда не сталкивался с проверенными и непроверенными контекстами. Отлично. – Llyle 2008-10-26 21:41:36

7

Обертка - это потому, что dfault C# не установлен. Если добавить «проверенный» блок, будет обнаружен перелив:

uint a = 3, b = 4; 
    checked 
    { 
     uint c = a - b; // throws an overflow 
    } 

Как для компилятора: он просто требует достоверных данных.

3

Это только значение по умолчанию - вы можете изменить настройки компиляции, чтобы включить проверку переполнения времени выполнения. Если вы включите это, исключения будут выбрасываться так, как вы ожидаете. В качестве альтернативы вы можете включить проверку определенной операции, поместив ее в выделенный блок.

uint c = checked(a - b); 
0

Вероятно, стоит уточнить, что здесь uint является беззнаковое INT, а не Unassigned внутр. Большая разница!

-2

Причина, по которой она обертывается отрицательной, связана с математикой Two's Complement, которая используется для целочисленной арифметики.

Короткий ответ: самый значащий бит используется в качестве знака. Нуль положителен; один отрицательный.

-1

Всегда используйте двойной.Разница в производительности незначительна, и она более гибкая и удобная. Эта практика предотвращает исключения и сокращает время разработки. Анальные люди ненавидят это, хотя.

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