在 C# 中检查 double 是不是为整数的好方法是啥? [复制]

Posted

技术标签:

【中文标题】在 C# 中检查 double 是不是为整数的好方法是啥? [复制]【英文标题】:What's a good way to check if a double is an integer in C#? [duplicate]在 C# 中检查 double 是否为整数的好方法是什么? [复制] 【发布时间】:2011-05-03 21:32:07 【问题描述】:

可能重复:How to determine if a decimal/double is an integer?

我有一个 double 类型的变量,我想检查它是否为整数。

目前有

public bool CheckIfInteger(double number)

    return number.ToString().Contains(".") == false;

有没有更好的办法?

更新:抱歉,我没有意识到可能造成混淆,整数是指整数的数学定义,即自然数加上非零自然数的负数。

【问题讨论】:

你的方式是有风险的:如果机器区域设置有“,”作为小数分隔符怎么办?看起来你可以从下面的答案中选择。 :) 您使用当前方法首先想到的是,它可能没有考虑到小数分隔符可能会因当前线程文化而异。如果您要从下面的答案中选择一种替代方案,请注意在给您结果之前将输入数字视为字符串的任何事情......特别是如果它不考虑除“。”之外的小数分隔符 @Shadow:您的情况可以通过CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator 解决。但是((decimal))Int32.MaxValue+1) 呢?这是一个没有小数分隔符的小数 看到所有针对这样一个基本问题的创造性解决方案有点酷。干杯。 不要学究气,但是...... Double 永远不会是 Integer。 Double 的值很可能是整数。我认为您的意思是“如果 Double 具有整数值”? 【参考方案1】:
return Math.Truncate(number) == number;

如 cmets 中所述,您可能需要考虑以下事实:您的号码的 double 表示可能不是一个精确的整数。在这种情况下,您需要考虑一些误差范围:

double diff = Math.Abs(Math.Truncate(number) - number);
return (diff < 0.0000001) || (diff > 0.9999999);

【讨论】:

但是,请注意浮点精度问题:使用double number = 100.0 * (8183.23 - 6695.37),您将使用此方法得到false 为什么要使用截断而不是舍入?使用 Round 您只需要针对小限制而不是大限制进行测试。示例: (以下是代码,但我不知道如何正确换行。) ``` lang-cs const double Epsilon = 1e-15; const double RelErr = Epsilon * precisionLoss; bool isInteger = Math.Abs​​(Math.Round(x) - x) 【参考方案2】:

如果你想检查一个整数,可以这样做:

public bool IsInteger(double number)

    return (number % 1 == 0);

如果您还想检查数字是否可以转换为 Int32:

public bool IsInt32(double number)

    return (number % 1 == 0) && number >= Int32.MinValue && number <= Int32.MaxValue;

【讨论】:

这在double值较大的情况下不起作用,double的取值范围大于int的取值范围。 TryParse 会因为范围而给你 false,但你的 mod 会返回 true。试试 double.MaxValue 感谢您的留言,更新了我的答案。 @BrokenGlass,@Tim:问题是“整数”,而不是“int”或“Int32”。 Tim 的原始逻辑是正确的,因为它匹配 OP 在问题中尝试的内容,对任何整数 double 返回 true,否则返回 false。 (理想情况下,OP 应该澄清它们是指Int32 还是整数。) @LukeH:尽管 C# 提供的任何整数数据类型都会失败,即使 Int64 不提供与 double 相同的范围。所以你说它是一个有效的整数检查是正确的,但是如果我不能将它存储在任何整数变量中,那对我实际上有什么用? @BrokenGlass:OP 是否说他们想将其存储在一个整数变量中?也许他们只是想知道它是否是一个整数。这就是问题所说的。 (正如我所说,理想情况下,OP 应该澄清它们的真正含义。)【参考方案3】:

使用字符串表示的缺陷在于使用的语言环境,您必须注意舍入问题。在大多数情况下,0.999999999 可以被认为是整数 1。这是一个考虑到舍入误差的小 sn-p:

Math.Abs(number - Math.Round(number)) < EPSILON

其中 EPSILON 是一个足以满足您的目的的双精度值,例如 0.00001

有关更多信息,另请参阅:http://msdn.microsoft.com/en-us/library/system.double.epsilon.aspx

【讨论】:

+1 用于提及 epsilon。【参考方案4】:

试试:

public bool CheckIfInteger(double number)

    return ((double) (int) number == number);

或者更漂亮的:

public bool CheckIfInteger(double number)

    return (Math.Floor(number) == number);

【讨论】:

你为什么要再次将 int 转换回 double 类型?【参考方案5】:

我会使用TryParse:

  double value = 2.0;
  int number;
  bool result = Int32.TryParse(value.ToString(), out number);

【讨论】:

【参考方案6】:
    public static bool CheckIfInteger(double number)
    
        return number - Math.Truncate(number) == 0;
    

【讨论】:

number == Math.Truncate(number) 怎么样?【参考方案7】:

我认为一个更好的问题是:我如何判断一个双精度数是否足够接近一个整数以被视为我的目的的整数?因为否则,您一定会遇到歧义。所以我会推荐这样的东西:

return Math.Abs(someDouble - Math.Round(someDouble)) < TOLERANCE;

【讨论】:

【参考方案8】:

我喜欢 abatishchev 使用 CurrentCulture 的想法。

return number.ToString().Contains(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator) == false;

这不能解决 epsilon 问题(我最初甚至没有考虑过)吗?

【讨论】:

【参考方案9】:

我使用以下字符串扩展方法来检查 RegEx 模式

   public static bool IsInteger(this string inputString)
    
        Regex regexInteger = new Regex(@"^[-]?\d+$");
        Match m = regexInteger.Match(inputString);
        return m.Success;
    

【讨论】:

这在很多情况下都不起作用,包括溢出,double的取值范围大于int的取值范围。你现在有两个问题。 当负数不表示为-1,而是表示为(1)时,这也会失败吗?

以上是关于在 C# 中检查 double 是不是为整数的好方法是啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中检查对象是不是为数字

如何检查程序是不是从自动启动运行?

检查文本框内容是不是为数字[重复]

C# - 检查是不是设置了整数属性

在C#中如何将int类型强制转换为double类型

在 C# 中获取字典最高值的键的好方法