Лучший способ обработки переполнения Integer в С#?
Обработка целочисленного переполнения является общей задачей, но как лучше всего справиться с ней на С#? Есть ли какой-нибудь синтаксический сахар, чтобы сделать его проще, чем с другими языками? Или это действительно лучший способ?
int x = foo();
int test = x * common;
if(test / common != x)
Console.WriteLine("oh noes!");
else
Console.WriteLine("safe!");
Ответы
Ответ 1
Мне не нужно было часто использовать это, но вы можете использовать checked keyword:
int x = foo();
int test = checked(x * common);
При переполнении приведет к исключению среды выполнения. Из MSDN:
В проверенном контексте, если выражение выражает значение, которое вне диапазона типа назначения результат зависит от является ли выражение постоянным или непостоянным. постоянная выражения вызывают ошибки времени компиляции, в то время как непостоянные выражения оцениваются во время выполнения и вызывают исключения.
Я также должен указать, что есть еще одно ключевое слово С#, unchecked
, которое, конечно же, делает противоположное от checked
и игнорирует переполнения. Вы могли бы задаться вопросом, когда вы когда-либо использовали unchecked
, поскольку он выглядит по умолчанию. Ну, есть опция компилятора С#, которая определяет, как обрабатываются выражения за пределами checked
и unchecked
: /checked. Вы можете установить его в соответствии с расширенными настройками сборки вашего проекта.
Если у вас есть много выражений, которые нужно проверить, самой простой задачей было бы установить параметр сборки /checked
. Тогда любое выражение, которое переполняется, если оно не завершено в unchecked
, приведет к исключению во время выполнения.
Ответ 2
Попробуйте выполнить
int x = foo();
try {
int test = checked (x * common);
Console.WriteLine("safe!");
} catch (OverflowException) {
Console.WriteLine("oh noes!");
}
Ответ 3
Лучший способ - использовать Micheal Said - использовать ключевое слово Checked.
Это можно сделать так:
int x = int.MaxValue;
try
{
checked
{
int test = x * 2;
Console.WriteLine("No Overflow!");
}
}
catch (OverflowException ex)
{
Console.WriteLine("Overflow Exception caught as: " + ex.ToString());
}
Ответ 4
Иногда самый простой способ - лучший. Я не думаю, что лучший способ написать то, что вы написали, но вы можете сократить его до:
int x = foo();
if ((x * common) / common != x)
Console.WriteLine("oh noes!");
else
Console.WriteLine("safe!");
Обратите внимание, что я не удалял переменную x
, потому что было бы глупо вызывать foo()
три раза.
Ответ 5
Итак, я столкнулся с этим далеко после факта, и это в основном отвечало на мой вопрос, но для моего конкретного случая (в случае, если кто-то еще имеет те же требования), я хотел что-нибудь, что переполнило бы положительное значение подписанного int, чтобы просто опуститься на int.MaxValue
:
int x = int.MaxValue - 3;
int someval = foo();
try
{
x += someval;
}
catch (OverflowException)
{
x = int.MaxValue;
}
Ответ 6
Старый поток, но я просто столкнулся с этим. Я не хотел использовать исключения. Я закончил с этим:
long a = (long)b * (long)c;
if(a>int.MaxValue || a<int.MinValue)
do whatever you want with the overflow
return((int)a);