Подтвердить что ты не робот

Почему int.MaxValue - int.MinValue = -1?

Насколько я понимаю, это должно привести к ошибке переполнения и когда я напишу его следующим образом:

public static void Main()
{

    Console.WriteLine(int.MaxValue - int.MinValue);
}

он правильно дал мне ошибку переполнения.

Однако:

public static void Main()
{

    Console.WriteLine(test());
}

public static Int32 test(int minimum = int.MinValue, int maximum = int.MaxValue)
{
    return maximum - minimum;
}

будет выводиться -1 Почему он это делает? Он должен выкинуть ошибку, потому что ее явно переполнение!

4b9b3361

Ответ 1

int.MaxValue - int.MinValue= значение, которое int не может удерживать. Таким образом, число обертывается назад до -1.

Это как 2147483647 - (- 2147483648) = 4294967295, который не является int

Поле Int32.MinValue

Значение этой константы -2,147,483,648;, то есть шестнадцатеричный 0x80000000.

И Поле Int32.MaxValue

Значение этой константы 2 147 483 647, то есть шестнадцатеричное 0x7FFFFFFF.

От MSDN

Когда происходит переполнение целых чисел, что происходит, зависит от выполнения контекст, который можно проверить или снять. В проверенном контексте Вызывается исключение OverflowException. В неконтролируемом контексте наиболее значимые биты результата отбрасываются и выполнение продолжается. Таким образом, С# дает вам выбор обработки или игнорирования переполнения.

Ответ 2

Это происходит из-за проверки переполнения кода во время компиляции. Строка

Console.WriteLine(int.MaxValue - int.MinValue);

на самом деле не будет ошибкой во время выполнения, он просто напишет "-1", но из-за проверки переполнения вы получите ошибку компиляции "Операция переполняется во время компиляции в режиме проверки".

Чтобы обойти проверку переполнения времени компиляции в этом случае, вы можете:

         unchecked
        {
            Console.WriteLine(int.MaxValue - int.MinValue);                
        }

Что будет нормально работать и вывести "-1"

Ответ 3

По умолчанию для уровня проекта на уровне проекта установлено значение "unchecked" по умолчанию. Вы можете включить проверку переполнения, перейдя к свойствам проекта, вкладке "Сборка", "Дополнительно". Всплывающее окно позволяет включить проверку переполнения. Инструмент .NET Fiddle, с которым вы ссылаетесь, кажется, выполняет некоторый дополнительный статический анализ, который мешает вам видеть истинное поведение в режиме реального времени. (Ошибка для вашего первого фрагмента кода выше: "Операция переполняется во время компиляции в режиме проверки". Вы не видите ошибку времени выполнения.)

Ответ 4

Я думаю, что это происходит даже дальше, чем переполнение.

если я посмотрю на это

 Int64 max = Int32.MaxValue;
 Console.WriteLine(max.ToString("X16")); // 000000007FFFFFFF
 Int64 min = Int32.MinValue;
 Console.WriteLine(min.ToString("X")); //FFFFFFFF80000000
 Int64 subtract = max - min;
 Console.WriteLine(subtract.ToString("X16")); //00000000FFFFFFFF <- not an overflow since it a 64 bit number
 Int32 neg = -1
 Console.WriteLine(neg.ToString("X")); //FFFFFFFF

Здесь вы видите, что если вы просто вычтите шестнадцатеричные значения) в 2 дополнениях, вы получите число -1 в 32-битном номере. (после транкинга ведущего 0

2 арифметики дополнения могут быть очень забавными http://en.wikipedia.org/wiki/Two 's_complement