Int или Uint или что - PullRequest
       40

Int или Uint или что

3 голосов
/ 14 февраля 2010

Рассмотрим это

        int i = 2147483647;
        var n = i + 3;
        i = n;

        Console.WriteLine(i);           // prints -2147483646    (1)
        Console.WriteLine(n);           // prints -2147483646    (2)
        Console.WriteLine(n.GetType()); // prints System.Int32   (3)

Меня смущают следующие

  • (1) как int может содержать значение -2147483646? (диапазон от -2 147 483 648 до 2 147 483 647)
  • (2) почему это печатает -2147483648, а не 2147483648 (компилятор должен выбрать лучший тип как диапазон int превышает)
  • (3) если он где-то конвертируется, почему n.GetType () выдает System.Int32

Edit1: Сделано исправление: Теперь вы получите то, что я получаю. (извините за это)

var n = i + 1; до

var n = i + 3;

Edit2: Еще одна вещь, если это переполнение, почему исключение не вызывается?

Добавление: при переполнении, не правильно ли устанавливать тип для

var n

в операторе var n = i + 3; для другого типа соответственно?


вы можете предложить лучший заголовок, так как это не имеет смысла для .... мне по крайней мере

Спасибо

Ответы [ 8 ]

6 голосов
/ 14 февраля 2010

Обновление : Постер исправил свой вопрос.

1) Это вывод ожидается, потому что вы добавили 3 к int.MaxValue, вызывая переполнение. В .NET по умолчанию это допустимая операция в неконтролируемом коде, дающая обтекание отрицательных значений, но если вы добавите блок checked вокруг кода, вместо этого будет OverflowException.

2) Тип переменной, объявленной с var, определяется во время компиляции, а не во время выполнения. Как правило, добавление двух Int32 дает Int32, а не UInt32, Int64 или что-то еще. Поэтому, хотя во время выполнения вы можете видеть, что результат слишком велик для Int32, он все равно должен возвращать Int32.

3) Он не преобразован в другой тип.

3 голосов
/ 14 февраля 2010

1)
Прежде всего, значение в переменной не -2147483646, это -2147483648. Запустите тест снова и проверьте результат.

Нет причины, по которой int не может содержать значение -2147483646. Это в пределах диапазона -2147483648..2147483647.

2)
Компилятор выбирает тип данных переменной как тип результата выражения. Выражение возвращает значение типа int, и даже если компилятор выберет больший тип данных для переменной, выражение все равно возвращает значение типа int, и вы получите то же значение, что и результат.

Это операция в выражении, которая переполняется, а не когда результат присваивается переменной, которая переполняется.

3)
Он нигде не конвертируется.

3 голосов
/ 14 февраля 2010
 1)  -2147483646 is bigger than -2,147,483,648
 2) 2147483648 is out of range
 3) int is an alias for Int32
1 голос
/ 14 февраля 2010

Это из-за битового представления

вы используете Int32, но то же самое относится и к символу (8 бит)

первый бит содержит знак, затем следующие биты содержат номер

так что с 7 битами вы можете представить 128 чисел 0111 1111

при попытке 129-го, 1000 0001, биты знака устанавливаются так, что компьютер думает, что его вместо -1

1 голос
/ 14 февраля 2010
  1. Это переполнение , ваш номер обернулся и стал отрицательным
  2. Это не работа компилятора, так как цикл во время выполнения может вызвать то же самое
  3. int - это псевдоним или System.Int32, они эквивалентны в .Net.
0 голосов
/ 14 февраля 2010

Если вы хотите создать исключение, напишите

abc = checked(i+3)

вместо этого. Это проверит на переполнение.

Кроме того, в c # по умолчанию не выдается исключение при переполнении. Но вы можете переключить эту опцию где-нибудь в свойствах вашего проекта.

0 голосов
/ 14 февраля 2010

Вы могли бы упростить это для всех нас, используя шестнадцатеричное обозначение.

Не все знают, что восьмое простое число Мерсенна - 0x7FFFFFFF

Просто скажи

0 голосов
/ 14 февраля 2010

Арифмические операции в .NET не изменяют фактический тип.
Вы начинаете с (32-битного) целого числа, и +3 не изменит этого.

Именно поэтому вы получаете неожиданный круглый номер, когда делаете это:

int a = 2147483647;
double b = a / 4;

или

int a = 2147483647;
var b = a / 4;

в этом отношении.

EDIT
Нет никаких исключений, потому что .NET переполняет число.
Исключение переполнения возникает только при операциях присваивания или, как объясняет Марк, когда вы устанавливаете условия для генерации исключения.

...