测试浮点数是否为整数

时间:2020-03-06 14:48:43  来源:igfitidea点击:

此代码有效(C3)

double d;
if(d == (double)(int)d) ...;
  • 有一个更好的方法吗?
  • 由于种种原因,我想避免双重投票。除此以外还有哪些不错的方法? (即使它们不那么好)

注意:几个人指出(重要)一点,即==通常是有问题的重整浮点数。在这种情况下,我期望值在0到几百之间,并且它们应该是整数(非整数是错误),因此,如果这些点"不应该"对我来说是个问题。

解决方案

我们不需要那里多余的(双精度)。这有效:

if (d == (int)d) {
 //...
}

d == Math.Floor(d)

换句话说,做同样的事情。

注意:希望我们知道在做这种事情时必须非常小心;浮点数/双精度数将很容易累积微小的错误,这些错误会使精确的比较(如此)没有明显的原因而失败。

像这样

double d = 4.0;
int i = 4;

bool equal = d.CompareTo(i) == 0; // true

使用Math.Truncate()

如果double是另一次计算的结果,则可能需要以下内容:

d == Math.Floor(d + 0.00001);

这样,如果有轻微的舍入错误,它仍然会匹配。

我认为这可以工作:

if (d % 1 == 0) {
  //...
}

我无法回答问题中特定于C#的部分,但是我必须指出,我们可能缺少带浮点数的通用问题。

通常,浮点数没有很好地定义整数。出于同样的原因,在浮点数上没有很好地定义相等性。浮点计算通常包括舍入误差和表示误差。

例如," 1.1 + 0.6!= 1.7"。

是的,这就是浮点数的工作方式。

这里," 1.1 + 0.6 1.7 == 2.2204460492503131e-16"。

严格来说,与浮点数比较最接近的事情是将浮点数与选定精度进行比较。

如果这还不够,则必须使用十进制数表示形式,具有内置误差范围的浮点数表示形式或者符号计算。

如果我们只是要转换它,Mike F / Khoth的回答很好,但还不能完全回答问题。如果我们要进行实际测试,并且确实很重要,那么我建议我们实施一些包含错误余量的操作。

例如,如果我们正在考虑使用钱,并且想要测试偶数金额,我们可能会说(遵循Khoth的模式):

if( Math.abs(d - Math.Floor(d + 0.001)) < 0.001)

换句话说,取值之差的绝对值和它的整数表示并确保它很小。

这将让我们选择所需的精度,加上或者减去半个刻度,以解决浮点漂移问题。比较也是不可或者缺的,这很好。

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

你能用这个吗

bool IsInt(double x)
    {
        try
        {
            int y = Int16.Parse(x.ToString());
            return true;
        }
        catch 
        {
            return false;
        }
    }