Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么要将.ToInt32(1.0/0.00004)!=(Int32)(1.0/0.00004)_C#_Math_.net 4.0_Casting_Clr - Fatal编程技术网

C# 为什么要将.ToInt32(1.0/0.00004)!=(Int32)(1.0/0.00004)

C# 为什么要将.ToInt32(1.0/0.00004)!=(Int32)(1.0/0.00004),c#,math,.net-4.0,casting,clr,C#,Math,.net 4.0,Casting,Clr,为什么要使用此代码 导致 假24999000000002500000000000 真的 在CLR/C实现的上下文中,浮点数学是不精确的。像0.2这样的简单值不能用二进制浮点数精确表示,而浮点数的有限精度意味着操作顺序的细微变化可能会改变结果。A必须阅读: IEEE标准将异常分为5类:溢出、下溢、零除、无效操作和不精确。每类异常都有一个单独的状态标志。前三个例外的含义不言而喻。无效操作包括表D-3中列出的情况,以及涉及NaN的任何比较 将主干转换为浮点数 (Int32)41.548==41 将数

为什么要使用此代码

导致

假24999000000002500000000000
真的


在CLR/C实现的上下文中,浮点数学是不精确的。像0.2这样的简单值不能用二进制浮点数精确表示,而浮点数的有限精度意味着操作顺序的细微变化可能会改变结果。A必须阅读:

IEEE标准将异常分为5类:溢出、下溢、零除、无效操作和不精确。每类异常都有一个单独的状态标志。前三个例外的含义不言而喻。无效操作包括表D-3中列出的情况,以及涉及NaN的任何比较


将主干转换为浮点数

(Int32)41.548==41

将数字四舍五入(功能?)

转换为32(41.548)=42


诀窍在于double的表示方式,因此(1.0/a)将以以下方式表示:

(1.0/a)=24999.9999999999636202119290828704833984375

当您使用cast时,您只得到该数字的第一部分,而convert方法的工作方式不同,下面是convert方法的代码:

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

,因此得到增量。

在计算中,
1.0/0.00004
的答案被转换为一个略小于2500的值,因为浮点数不能精确地表示所有可能的值。鉴于此,

为什么这两个整数的值不同?

将double强制转换为int,因此小数点后的所有内容都将被丢弃

Convert.ToInt32

为什么浮点数不精确?

请参阅另一个答案中链接的优秀文章:

如何精确地表示值?


您可以使用十进制类型而不是双精度类型。这样做有优点也有缺点,请参见

一个问题,但该文档是否涵盖了强制转换和转换之间的区别,因为它是一个相当长的文档。您能否提供更多关于CLR实现的细节,这些细节彼此不同?您阅读了该问题吗?因为我不确定代码的精度。这是关于
Convert
的区别,它不是一个特性,它是完全记录的行为(请参阅),这并不能解释为什么((int)(1.0/(1.0/25000))==24999@diimdeep,因为
1.0/0.0004==24999.99999999996
。我已经编辑了我以前的评论,请参阅相关问题。什么?实际(1.0/0.00004)=25000@diimdeep,在
double r=1.0/0.0004后设置断点并查看
r
值。你会感到惊讶:)。
0.00004
不具有代表性这回答了问题。
public static int ToInt32(double value)
{
    if (value >= 0.0)
    {
        if (value < 2147483647.5)
        {
            int num = (int)value;
            double num2 = value - (double)num;
            if (num2 > 0.5 || (num2 == 0.5 && (num & 1) != 0))
            {
                num++;
            }
            return num;
        }
    }
    else
    {
        if (value >= -2147483648.5)
        {
            int num3 = (int)value;
            double num4 = value - (double)num3;
            if (num4 < -0.5 || (num4 == -0.5 && (num3 & 1) != 0))
            {
                num3--;
            }
            return num3;
        }
    }
    throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
}
int num = (int)value;
double num2 = value - (double)num;

24999.99999999999636202119290828704833984375 - 24999 > 0.5