Почему это не переполняется?
-
13-09-2019 - |
Вопрос
Учитывая этот код:
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));
}
}
}
Вы можете найти информацию о checked
(и unchecked
) в 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 миллиардов.
в 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, оно не будет компилироваться!