C# 为什么要将.ToInt32(1.0/0.00004)!=(Int32)(1.0/0.00004)
为什么要使用此代码 导致 假24999000000002500000000000C# 为什么要将.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 将数
真的
在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