C# 测试浮点数是否为整数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/142252/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 15:17:13  来源:igfitidea点击:

Test if a floating point number is an integer

提问by BCS

This code works (C# 3)

此代码有效(C# 3)

double d;
if(d == (double)(int)d) ...;
  1. Is there a better way to do this?
  2. For extraneous reasons I want to avoid the double cast so; what nice ways exist other than this? (even if they aren't as good)
  1. 有一个更好的方法吗?
  2. 由于无关的原因,我想避免双重转换;除了这个还有什么好方法?(即使他们没有那么好)

Note:Several people pointed out the (important) point that == is often problematic regrading floating point. In this cases I expect values in the range of 0 to a few hundred and they are supposed to be integers (non ints are errors) so if those points "shouldn't" be an issue for me.

注意:有几个人指出(重要的)点 == 通常在重新计算浮点数时会出现问题。在这种情况下,我期望值在 0 到几百范围内,并且它们应该是整数(非整数是错误)所以如果这些点“不应该”对我来说是个问题。

采纳答案by swilliams

d == Math.Floor(d)

does the same thing in other words.

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

NB: Hopefully you're aware that you have to be very careful when doing this kind of thing; floats/doubles will very easily accumulate miniscule errors that make exact comparisons (like this one) fail for no obvious reason.

NB:希望你知道在做这种事情时你必须非常小心;浮点数/双精度数很容易累积微小的错误,导致精确比较(如这个)无缘无故失败。

回答by swilliams

You don't need the extra (double) in there. This works:

你不需要那里的额外(双)。这有效:

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

回答by Darren Kopp

Something like this

像这样的东西

double d = 4.0;
int i = 4;

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

回答by Micha? Piaskowski

Use Math.Truncate()

使用 Math.Truncate()

回答by Khoth

If your double is the result of another calculation, you probably want something like:

如果你的 double 是另一个计算的结果,你可能想要这样的东西:

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

That way, if there's been a slight rounding error, it'll still match.

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

回答by VoxPelli

This would work I think:

我认为这会起作用:

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

回答by ddaa

I cannot answer the C#-specific part of the question, but I must point out you are probably missing a generic problem with floating point numbers.

我无法回答问题中特定于 C# 的部分,但我必须指出您可能遗漏了一个浮点数的通用问题。

Generally, integerness is not well defined on floats. For the same reason that equality is not well defined on floats. Floating point calculations normally include both rounding and representation errors.

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

For example, 1.1 + 0.6 != 1.7.

例如,1.1 + 0.6 != 1.7

Yup, that's just the way floating point numbers work.

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

Here, 1.1 + 0.6 - 1.7 == 2.2204460492503131e-16.

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

Strictly speaking, the closest thing to equality comparison you can do with floats is comparing them up to a chosen precision.

严格来说,你可以用浮点数做的最接近等式比较的事情是将它们与选定的 precision进行比较。

If this is not sufficient, you must work with a decimal number representation, with a floating point number representation with built-in error range, or with symbolic computations.

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

回答by Bill K

If you are just going to convert it, Mike F / Khoth's answer is good, but doesn't quite answer your question. If you are going to actually test, and it's actually important, I recommend you implement something that includes a margin of error.

如果您只是要转换它,Mike F / Khoth 的回答很好,但并不能完全回答您的问题。如果您要进行实际测试,而且它实际上很重要,我建议您实施一些包含误差幅度的内容。

For instance, if you are considering money and you want to test for even dollar amounts, you might say (following Khoth's pattern):

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

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

In other words, take the absolute value of the difference of the value and it's integer representation and ensure that it's small.

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

回答by loudej

This will let you choose what precision you're looking for, plus or minus half a tick, to account for floating point drift. The comparison is integral also which is nice.

这将让您选择您正在寻找的精度,加上或减去半个刻度,以解决浮点漂移。比较也是不可或缺的,这很好。

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);
        }
    }
}

and the output is

输出是

2 is an int
1.99999999 is an int
2.00000001 is an int

回答by Crash893

Could you use this

你能用这个吗

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