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);