【问题标题】:Why does this throw an OverflowException?为什么这会引发溢出异常?
【发布时间】:2014-01-07 21:53:40
【问题描述】:

我在将任意数字转换为字节的方法中有以下代码:

try {
    return (byte) Convert.ChangeType(operand.RealValue, TypeCode.Byte);
}
catch (OverflowException) {
    if (AllowArithmeticOverflow) {
        unchecked {
            decimal d = Convert.ToDecimal(operand.RealValue);
            return (byte) d;
        }
    }

    throw;
}

在此代码中,operand.RealValue 应为任意数字。对于我正在测试的示例,它是一个 sbyte,其值为 -13(已通过调试器验证)。我可以在调试器中单步执行并到达return (byte) d; 行...此时会引发OverflowException,尽管它位于unchecked 块中。

那么...是什么给了?

另外,如果您正在查看我的实现并想知道我到底在做什么 - 这是我迄今为止尝试过的所有体操的结果,没有得到这个例外。必须简洁的答案获胜:)

注意:异常信息如下:

System.OverflowException:值太大或太小 一个无符号字节。 ---> System.OverflowException: 值也是 对于 UInt32 来说太大或太小。

【问题讨论】:

  • -13 对于无符号字节来说太小了
  • 是的,很明显 - 但我还是想允许这样做,基本上只是 reinterpret_cast 它......
  • @SwDevMan81 赢了!再简洁不过了。
  • 那么-13应该对应什么字节值呢? 242? 115? 0?
  • 但原因是因为unchecked是用于算术运算和转换:The unchecked keyword is used to suppress overflow-checking for integral-type arithmetic operations and conversions.

标签: c# unchecked-conversion


【解决方案1】:

显然没有办法将-13 解释为一个字节。至少不会,除非您指定一些额外的上下文。也许您的意思是将-13 视为无符号字符(值介于-128 和127 之间),然后将这些位重新解释为有符号字符(字节)。

如果这是您想要做的,那么您可以使用 BitConverter 类。

【讨论】:

    【解决方案2】:

    该异常是由使用 Convert.ChangeType.. 引起的。这就是为什么 unchecked 块在各种情况下可能无法正常工作(以及为什么您无疑会发布此问题)。

    Convert.ChangeType 最终调用IConvertible.To<TypeHere>System.SByte上的ToByte方法是这样的:

    public static byte ToByte(sbyte value) {
        if (value < 0) {
            throw new OverflowException(Environment.GetResourceString("Overflow_Byte"));
        }
    
        return (byte)value;
    }
    

    它明确地抛出异常..因此为什么unchecked 没用。

    【讨论】:

    • 他说return语句上的断点命中。他显然已经克服了转化
    【解决方案3】:

    来自您的评论:

    基本上只是 reinterpret_cast 它...

    我了解到您想将 sbyte 转换为值 -13 并将其解释为 byte

    所以简单地转换它:

    sbyte s = -13;
    byte u = (byte)s; // u = 243
    

    【讨论】:

    • 你可以做同样的事情,只需转换为sbyte,然后转换为byte。这将是更清晰的代码。
    • 出于某种原因,我认为这会弄乱标志......它最终不会是+13吗?
    • 自己试试看。结果是一样的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-13
    • 2018-07-10
    • 2016-12-29
    • 1970-01-01
    • 2021-09-25
    • 2021-11-05
    相关资源
    最近更新 更多