zoukankan      html  css  js  c++  java
  • 关于System.Convert.ToInt16(float value)抛异常System.OverflowException---值对于 Int32 太大或太小的原因的探究

    前面有个案例最终查明原因是System.Convert.ToInt16的调用导致溢出异常:

    0:000> !PrintException /d 4ee2e8f4
    Exception object: 4ee2e8f4
    Exception type:   System.OverflowException
    Message:          值对于 Int32 太大或太小
    InnerException:   <none>
    StackTrace (generated):
        SP       IP       Function
        001EC094 1D3D8831 mscorlib_ni!System.Convert.ToInt32(Double)+0xc4bc19
    当时核对了代码,代码里明明调用的是System.Convert.ToInt16(float value),为什么这里却抛出异常是调用System.Convert.ToInt32(Double)引起的呢。

    要想查明原因,只有查看源代码。那我们看看DotNet48RTM的源代码:

    在工程mscorlib的代码..DotNet48RTMSource dpclrsrcBCLsystemconvert.cs我们可以找到相关代码

    public static short ToInt16(float value) {
                return ToInt16((double)value);
            }

    可知ToInt16(float value)调用的是ToInt16(double value) ,那么ToInt16(double value) 的代码如下:

    public static short ToInt16(double value) {
                return ToInt16(ToInt32(value));
            }

    可知ToInt16(double value)调用的是ToInt32(double value),ToInt32(double value)的代码如下:

     public static int ToInt32(double value) {
                if (value >= 0) {
                    if (value < 2147483647.5) {
                        int result = (int)value;
                        double dif = value - result;
                        if (dif > 0.5 || dif == 0.5 && (result & 1) != 0) result++;
                        return result;
                    }
                }
                else {
                    if (value >= -2147483648.5) {
                        int result = (int)value;
                        double dif = value - result;
                        if (dif < -0.5 || dif == -0.5 && (result & 1) != 0) result--;
                        return result;
                    }
                }
                throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
            }

    此时,我们也就明白了为什么抛出的是“值对于 Int32 太大或太小”的异常了,同时,我也比较担忧着个性能的问题。

  • 相关阅读:
    STL容器 erase的使用陷井
    转:VC++线程同步-事件对象
    VC线程同步方法
    C/C++四种退出线程的方法
    rabbitMQ 常用命令
    Spring @Configuration
    Spring RabbitMQ 延迟队列
    rabbitmq web管理界面 用户管理
    Linux下tar.gz 安装
    Linux下RPM软件包的安装及卸载
  • 原文地址:https://www.cnblogs.com/yilang/p/12826527.html
Copyright © 2011-2022 走看看