ArithmeticException в непроверенном коде в C#

Мы получаем ArithmeticException (переполнение или недостаточное значение в арифметической операции.) В следующей строке на клиентском компьютере. Мы не можем воспроизвести его на любом компьютере (клиентском или нашем):

var actualFullness = (byte)((hdd.Capacity - hdd.FreeSpace) / (float)hdd.Capacity * 100);

где hdd.Capacity а также hdd.FreeSpace являются uint, Значения взяты из функции в нативной DLL.

Мы используем НЕТ checked или же unchecked ключевые слова в программе. Мы НЕ используем / проверены опции компилятора.

Он написан на.NET 4 и работает как 32-битный процесс.

Есть идеи, почему выбрасывается это исключение?

2 ответа

Исключение не вызывает арифметика, показанная в вопросе. Эта программа покрывает крайние случаи и прекрасно работает:

class Program
{
    static byte test(uint capacity, uint free)
    {
        return (byte)((capacity - free) / (float)capacity * 100);
    }

    static void Main(string[] args)
    {
        Console.WriteLine(test(uint.MaxValue, uint.MaxValue));
        Console.WriteLine(test(0, 0));
        Console.WriteLine(test(uint.MaxValue, 0));
        Console.WriteLine(test(0, uint.MaxValue));
    }
}

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

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

ArithmeticException является базовым классом для DivideByZeroException, NotFiniteNumberException, а также OverflowException, Как правило, один из производных классов ArithmeticException будет выброшен для более точного указания точного характера ошибки.

Поскольку вы не получили ни одного из этих более конкретных, чем-то не так с вашим выражением лица. Capacity или же FreeSpace Геттер являются кандидатами для изучения.

Я проверил следующий код для различных сценариев, и если работал

uint Capacity = 100; //110; uint.MaxValue;  0
uint FreeSpace = 110;//100; 0;              uint.MaxValue
var actualFullness = (byte)((Capacity - FreeSpace) / (float)Capacity * 100);
Другие вопросы по тегам