Вопрос

Подумайте об этом

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

Редактировать 1: Внес коррективы:Теперь вы получите То, что получаю я.(прошу прощения за это)

значение n = i + 1;Для

значение n = i + 3;

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

Дополнение: когда происходит переполнение, разве неправильно устанавливать тип для

вар н

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


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

Спасибо

Это было полезно?

Решение

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

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

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

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

Другие советы

 1)  -2147483646 is bigger than -2,147,483,648
 2) 2147483648 is out of range
 3) int is an alias for Int32

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

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

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

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

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

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

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

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

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

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

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

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

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

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

или

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

если уж на то пошло.

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

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

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

Просто говорю

Если вы хотите, чтобы было сгенерировано исключение, напишите

abc = checked(i+3)

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top