【问题标题】:ArithmeticException in unchecked code in C#C# 中未经检查的代码中的 ArithmeticException
【发布时间】:2014-04-23 09:10:16
【问题描述】:

我们在客户机器上的以下行中得到 ArithmeticException(算术运算中溢出或下溢。)。我们无法在任何 PC(客户或我们的)上复制它:

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

其中hdd.Capacityhdd.FreeSpaceuint。值来自本机 DLL 中的函数。

我们在程序中使用 NO checkedunchecked 关键字。我们不使用 /checked 编译器选项。

它是用 .NET 4 编写的,并且作为 32 位进程运行。

知道为什么会抛出这个异常吗?

【问题讨论】:

  • uint/float 你把它转换成字节?
  • 在执行算术运算之前,您是否记录了CapacityFreeSpace 的值?这将有助于诊断。
  • 有没有可能你的容量小于可用空间(无论什么原因),然后会导致负值
  • 为什么要使用另一个 DLL 来获取这些信息? WMI(例如来自Win32_LogicalDricve)。值得注意的是,WMI 中的 FreeSpace 和 Capacity 值为 uint64。超过 4GB 的分区会导致该表达式出现溢出问题。
  • 虽然这似乎是一个非常有趣的问题,但我投票以“缺乏足够的信息”为由结束这个问题,仅仅是因为这里有太多的未知数,任何人都无法得出结论性的答案。 DLL 的输出是什么?我们在谈论什么单位?抛出此异常的硬盘驱动器的容量和可用空间值是多少?容量和可用空间值是否准确(意味着您从 DLL 获得的值与 WMI 告诉您的一致)?

标签: c# .net-4.0 checked unchecked arithmeticexception


【解决方案1】:

问题中显示的算术不会引发异常。该程序涵盖了边缘情况并且运行良好:

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

事实上,通过静态分析很容易看出问题中的表达式与错误无关。

所以您似乎确实误诊了故障。也许您引用的本机代码以某种方式触发了异常。无论如何,唯一要说的是,您需要更深入地挖掘并尝试对问题进行正确的诊断。

【讨论】:

    【解决方案2】:

    ArithmeticExceptionDivideByZeroExceptionNotFiniteNumberExceptionOverflowException 的基类。通常,将抛出 ArithmeticException 的派生类之一,以更准确地指示错误的确切性质。

    由于您没有得到任何更具体的内容,因此您的表达背后有问题。 CapacityFreeSpace getter 是值得研究的候选对象。

    我检查了以下代码是否适用于不同的场景

    uint Capacity = 100; //110; uint.MaxValue;  0
    uint FreeSpace = 110;//100; 0;              uint.MaxValue
    var actualFullness = (byte)((Capacity - FreeSpace) / (float)Capacity * 100);
    

    【讨论】:

    • Capacity 和 FreeSpace 是简单的自动属性,带有私有设置器。两者都在构造函数中设置
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2018-01-04
    • 2011-06-09
    相关资源
    最近更新 更多