Как изящно проверить на ситуации переполнения в C #? - PullRequest
4 голосов
/ 06 февраля 2009

Обновление: я собираюсь оставить все как есть: снижение производительности исключения (очень редкое) лучше, чем, вероятно, снижение производительности при проверке каждой операции (общее)


Я пытаюсь поддержать «EstimatedRowCount», который в одном случае был бы продуктом двух вложенных курсоров, объединенных вместе:

estimatedRowCount = left.EstimatedRowCount * right.EstimatedRowCount;
return estimatedRowCount;

Конечно, если левая и правая части достаточно велики, это вызовет исключение OverflowException.

Здесь меня не волнует, точная ли оценочнаяRowCount на 100%, достаточно большая, чтобы знать, что этот курсор содержит много данных.

Прямо сейчас я делаю это:

// We multiply our rowcount
Int64 estimRowCount = 0;
try
{
    estimRowCount = leftRowCount * rightRowCount;
}
catch (OverflowException)
{
    // Ignore overflow exceptions
    estimRowCount = Int64.MaxValue;
}

return estimRowCount;

Есть ли лучший способ протестировать операции переполнения, чтобы мне не нужно было делать попытку {} catch для защиты?

Ответы [ 3 ]

4 голосов
/ 06 февраля 2009
<code>
if (Int64.MaxValue / leftRowCount <= rightRowCount)
{
    estimRowCount = leftRowCount * rightRowCount
}
else
{
    estimRowCount = Int64.MaxValue;
}

Не уверен, смогу ли я объяснить себя без редактора. Но я надеюсь, что вы поняли идею.

4 голосов
/ 06 февраля 2009

Это хороший пример использования ключевого слова 'unchecked' .

Чтобы использовать, просто оберните свое назначение в блок 'unchecked':

Int64 estimRowCount = 0;
unchecked
{
    estimRowCount = leftRowCount * rightRowCount;
}

Затем проверьте, отрицательный ли результат - если он есть, он переполнен:

if (estimRowCount > 0) estimRowCount = Int64.MaxValue;

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

3 голосов
/ 06 февраля 2009

Ваше решение кажется вполне разумным. Есть что-то конкретное, что вы хотите оптимизировать? Вызывает ли этот продукт состояние переполнения так часто, что вас беспокоит снижение производительности при обработке исключений?

(Просто простая пища для размышления, если leftRowCount и rightRowCount имеют значение Int32, а не Int64, тогда ваш продукт не может переполнить значение Int64 estimRowCount lvalue.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...