Вопрос

Учитывая этот код:

int x = 20000;
int y = 20000;
int z = 40000;

// Why is it printing WTF? Isn't 40,000 > 32,767?
if ((x + y) == z) Console.WriteLine("WTF?");

И знание int может содержать от -32,768 до +32,767.Почему это не вызывает переполнения?

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

Решение

В C #, the int тип сопоставляется с Int32 тип, который всегда является 32-разрядным, подписанный.

Даже если вы используете short, он все равно не переполнится, потому что short + short возвращает int по умолчанию.Если вы разыграете это int Для short - (short)(x + y) - вы получите переполненное значение.Однако вы не получите исключения.Вы можете использовать checked поведение для получения исключения:

using System;

namespace TestOverflow
{
    class Program
    {
        static void Main(string[] args)
        {
            short x = 20000;
            short y = 20000;
            short z;

            Console.WriteLine("Overflowing with default behavior...");
            z = (short)(x + y);
            Console.WriteLine("Okay! Value is {0}. Press any key to overflow " +
                "with 'checked' keyword.", z);
            Console.ReadKey(true);

            z = checked((short)(x + y));
        }
    }
}

Вы можете найти информацию о checkedunchecked) в MSDN.В основном это сводится к производительности, потому что проверка на переполнение происходит немного медленнее, чем его игнорирование (и именно поэтому поведение по умолчанию обычно unchecked, но я готов поспорить , что в некоторых компиляторах / конфигурациях вы получите исключение при первом z задание.)

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

http://msdn.microsoft.com/en-us/library/5kzh1b5w.aspx

Тип:int Диапазон:-2,147,483,648 - 2,147,483,647

Хотя все правы, говоря, что тип "int" на 32-разрядной машине, скорее всего, равен 2 ^ 32, в вашей методологии есть вопиющий недостаток.

Давайте предположим, что int был 16-битным.Вы присваиваете значение, которое будет переполнять z, поэтому само z будет переполнено.Когда вы вычисляете x + y, вы также переполняете тип int, очень вероятно, что оба случая будут переполнены до одного и того же значения, что означает, что вы все равно достигнете равенства (вероятно, это зависит от компилятора, я не совсем уверен, будет ли повышен x + y).

Правильный способ провести ваш эксперимент состоял бы в том, чтобы z имел больший тип данных, чем x и y.Например (Извините за простой C, я не очень разбираюсь в C #.Однако, надеюсь, это проиллюстрировало методологию.)

int x = INT_MAX;
int y = INT_MAX;
int sum = x + y;
long long z = INT_MAX+INT_MAX;
if(sum == z) 
 printf("Why didn't sum overflow?!\n");

Сравнение sum и z важно, поскольку сравнение x + y и z все еще может получиться нормально в зависимости от того, как компилятор обрабатывает продвижение.

В C # значение Int равно 4 байтам.Таким образом, он достигает максимума в 2 ^ 31 или 2,147,483,648.Если вам нужно 2-байтовое целое число, используйте short вместо int .

Потому что int в .NET - это подписанный 32 бит число с диапазоном -2,147,483,648 - 2,147,483,647.

Ссылка : http://msdn.microsoft.com/en-us/library/5kzh1b5w (ПРОТИВ 80).aspx

Потому что целые числа являются 32-разрядными и содержат значения до ± 2 ГБ.

Размер int равен 4 байтам, поэтому он может содержать по крайней мере 2 ^ 31, что составляет около 2 миллиардов.

В инт сопоставление ключевых слов с .NET Framework Тип Int32, который может содержать целые числа в диапазоне от -2 147 483 648 до 2 147 483 647.

в C# int (System.Int32) состоит из 32 бит, которые могут с радостью хранить это значение.

вам дано распечатать результат как "WTF?" . Тогда как он должен отображать другое значение?

Int означает int32, его диапазон составляет от -2147483648 до 2147483647 вам будет предоставлен диапазон int16: от -32768 до 32767

Это причина, по которой он не выдает никакой ошибки

Во-первых, ваш код находится в диапазоне для int...Однако, если бы его не было в пределах досягаемости, то он тоже не стал бы жаловаться...потому что вы никогда не присваиваете значение обратно какой-либо переменной после выполнения X + Y в вашей проверке if...

Предположим, если бы вы выполняли X * Y, то оно было бы вычислено, и результатом было бы длинное значение, затем значение из переменной Z берется и повышается до long, после чего оба будут сравнены...Помните, что преобразование из примитива нижнего диапазона в значение примитива верхнего диапазона является неявным.

int x = 200000; //In your code it was 20000
int y = 200000; //In your code it was 20000
int z = 40000;

// Why is it printing WTF? Isn't 40,000 > 32,767?
// Note: X + Y = 200000 and not < 32,767 
// would pass compiler coz you are not assigning and values are compared as longs
// And since it's not equals to 40,000 the WTF did not got printed
if ((x + y) == z) Console.WriteLine("WTF?");     
// And x * y >= z is true WTF MULTIPLY got printed
if ((x * y) >= z) Console.WriteLine("WTF MULTIPLY?"); 
// Compiler would fail since x can't hold 40,00,00,00,000
x = x * y; 

Все вышесказанное верно, однако важно знать, что если вы присвоите число больше 2 ^ 32, оно не будет компилироваться!

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