此代码有效(C#3)
double d;
if(d == (double)(int)d) ...;
注意:有几个人指出(重要的)点= =经常有问题重新浮点数。在这种情况下,我期望值在0到几百的范围内,它们应该是整数(非整数是错误),所以如果这些点“不应该”对我来说是一个问题。
答案 0 :(得分:27)
d == Math.Floor(d)
换句话说,做同样的事情。
NB:希望你知道做这种事情时你必须非常小心;浮点/双打很容易积累微小的错误,使得精确的比较(如本例)失败没有明显的原因。答案 1 :(得分:5)
如果你的双倍是另一次计算的结果,你可能想要这样的东西:
d == Math.Floor(d + 0.00001);
这样,如果出现轻微的舍入错误,它仍会匹配。
答案 2 :(得分:5)
我认为这可行:
if (d % 1 == 0) {
//...
}
答案 3 :(得分:5)
我无法回答问题的C#特定部分,但我必须指出你可能错过了浮点数的一般问题。
通常,在浮点数上没有很好地定义整数。出于同样的原因,在浮点数上没有很好地定义相等性。浮点计算通常包括舍入和表示错误。
例如,1.1 + 0.6 != 1.7
。
是的,这就是浮点数的工作方式。
此处1.1 + 0.6 - 1.7 == 2.2204460492503131e-16
。
严格来说,与浮点数相比,最接近相等比较的是将与选择的精度进行比较。
如果这还不够,则必须使用十进制数表示,带有内置误差范围的浮点数表示,或者使用符号计算。
答案 4 :(得分:3)
如果你要转换它,Mike F / Khoth的答案很好,但并没有完全回答你的问题。如果您要进行实际测试,并且实际上非常重要,我建议您实施一些包含误差的内容。
例如,如果你正在考虑金钱并且想要测试甚至是美元金额,你可能会说(按照Khoth的模式):
if( Math.abs(d - Math.Floor(d + 0.001)) < 0.001)
换句话说,取值的差值的绝对值和它的整数表示,并确保它很小。
答案 5 :(得分:2)
你不需要额外的(双)。这有效:
if (d == (int)d) {
//...
}
答案 6 :(得分:2)
使用Math.Truncate()
答案 7 :(得分:2)
对于任何固定精度的FP编号,在数学上确保一个简单的测试,例如'x == floor(x)'可以正常工作。
所有合法的固定精度FP编码都代表不同的实数,因此对于每个整数x,最多只有一个固定精度FP编码与其完全匹配。
因此,对于以这种方式表示的每个整数x,我们必须有x == floor(x),因为floor(x)按定义返回最大的FP数y,使得y <= x和y代表一个整数;所以floor(x)必须返回x。
答案 8 :(得分:1)
这将允许您选择要查找的精度,加上或减去半个刻度,以解释浮点漂移。比较也是不可或缺的,这很好。
static void Main(string[] args)
{
const int precision = 10000;
foreach (var d in new[] { 2, 2.9, 2.001, 1.999, 1.99999999, 2.00000001 })
{
if ((int) (d*precision + .5)%precision == 0)
{
Console.WriteLine("{0} is an int", d);
}
}
}
,输出
2 is an int
1.99999999 is an int
2.00000001 is an int
答案 9 :(得分:0)
像这样的东西
double d = 4.0;
int i = 4;
bool equal = d.CompareTo(i) == 0; // true
答案 10 :(得分:0)
你能用这个
吗? bool IsInt(double x)
{
try
{
int y = Int16.Parse(x.ToString());
return true;
}
catch
{
return false;
}
}
答案 11 :(得分:0)
要处理双精度......
Math.Abs(d - Math.Floor(d)) <= double.Epsilon
考虑以下情况,其中小于double.Epsilon 的值无法比较为零。
// number of possible rounds
const int rounds = 1;
// precision causes rounding up to double.Epsilon
double d = double.Epsilon*.75;
// due to the rounding this comparison fails
Console.WriteLine(d == Math.Floor(d));
// this comparison succeeds by accounting for the rounding
Console.WriteLine(Math.Abs(d - Math.Floor(d)) <= rounds*double.Epsilon);
// The difference is double.Epsilon, 4.940656458412465E-324
Console.WriteLine(Math.Abs(d - Math.Floor(d)).ToString("E15"));