如何确定十进制/双精度是否为整数?

时间:2010-05-01 21:25:25

标签: c#

如何判断小数或双精度值是否为整数?

例如:

decimal d = 5.0; // Would be true
decimal f = 5.5; // Would be false

double d = 5.0; // Would be true
double f = 5.5; // Would be false

我想知道这个的原因是我可以通过编程方式确定是否要使用.ToString("N0").ToString("N2")输出值。如果没有小数点值,那么我不想显示它。

16 个答案:

答案 0 :(得分:360)

对于浮点数,n % 1 == 0通常是检查小数点后是否有任何内容的方法。

public static void Main (string[] args)
{
    decimal d = 3.1M;
    Console.WriteLine((d % 1) == 0);
    d = 3.0M;
    Console.WriteLine((d % 1) == 0);
}

输出:

False
True

更新: 正如@Adrian Lopez在下面提到的,与较小值epsilon进行比较会丢弃浮点计算错误计算。由于问题是关于double值,因此下面将是更多浮点计算证明答案:

Math.Abs(d % 1) <= (Double.Epsilon * 100)

答案 1 :(得分:44)

有很多方法可以做到这一点。例如:

double d = 5.0;
bool isInt = d == (int)d;

您也可以使用modulo。

double d = 5.0;
bool isInt = d % 1 == 0;

答案 2 :(得分:15)

这个怎么样?

public static bool IsInteger(double number) {
    return number == Math.Truncate(number);
}

decimal的相同代码。

实际上,Mark Byers提出了一个很好的观点:这可能不是你真正想要的。如果真正关心的是舍入到最接近的两位小数的数字是否为整数,则可以改为:

public static bool IsNearlyInteger(double number) {
    return Math.Round(number, 2) == Math.Round(number);
}

答案 3 :(得分:12)

虽然提出的解决方案似乎适用于简单的示例,但总的来说这样做是个坏主意。一个数字可能不是一个整数,但是当你尝试格式化它时,它足够接近你得到1.000000的整数。如果你做一个理论上应该给出1的计算,但实际上由于舍入误差而给出一个非常接近但不完全等于1的数字,就会发生这种情况。

相反,首先对其进行格式化,如果您的字符串以句点结尾,后跟零,则将其删除。您还可以使用一些格式自动删除尾随零。这可能足以满足您的目的。

double d = 1.0002;
Console.WriteLine(d.ToString("0.##"));
d = 1.02;
Console.WriteLine(d.ToString("0.##"));

输出:

1
1.02

答案 4 :(得分:10)

bool IsInteger(double num) {
    if (ceil(num) == num && floor(num) == num)
        return true;
    else
        return false;
}

Problemo solvo。

编辑:Mark Rushakoff表示。

答案 5 :(得分:4)

如果Int32的上限和下限很重要:

public bool IsInt32(double value)
{
    return  value >= int.MinValue && value <= int.MaxValue && value == (int)value;
}

答案 6 :(得分:3)

Mark Rushakoff的回答可能更简单,但由于没有隐式的除法操作,以下内容也可以更有效:

     bool isInteger = (double)((int)f) == f ;

     bool isInteger = (decimal)((int)d) == d ;

如果你想要两种类型的单个表达式,也许

     bool isInteger = (double)((int)val) == (double)val ;

答案 7 :(得分:3)

static bool IsWholeNumber(double x) 
{
    return Math.Abs(x % 1) < double.Epsilon;
}

答案 8 :(得分:2)

您可以对double类型使用String格式。这是一个例子:

double val = 58.6547;
String.Format("{0:0.##}", val);      
//Output: "58.65"

double val = 58.6;
String.Format("{0:0.##}", val);      
//Output: "58.6"

double val = 58.0;
String.Format("{0:0.##}", val);      
//Output: "58"

如果这没有用,请告诉我。

答案 9 :(得分:1)

    public static bool isInteger(decimal n)
    {
        return n - (Int64)n == 0;
    }

答案 10 :(得分:0)

我遇到了类似的情况,但其中的值是一个字符串。用户键入一个应该是美元金额的值,因此我想验证它是否为数字,并且最多有两位小数。

如果字符串“s”表示最多两位小数的数字,那么我的代码返回true,否则返回false。它避免了由于浮点值不精确而导致的任何问题。

try
{
    // must be numeric value
    double d = double.Parse(s);
    // max of two decimal places
    if (s.IndexOf(".") >= 0)
    {
        if (s.Length > s.IndexOf(".") + 3)
            return false;
    }
    return true;
catch
{
    return false;
}

我在http://progblog10.blogspot.com/2011/04/determining-whether-numeric-value-has.html更详细地讨论了这个问题。

答案 11 :(得分:0)

使用int.TryParse将产生以下结果:   var shouldBeInt = 3;

        var shouldntBeInt = 3.1415;

        var iDontWantThisToBeInt = 3.000f;

        Console.WriteLine(int.TryParse(shouldBeInt.ToString(), out int parser)); // true

        Console.WriteLine(int.TryParse(shouldntBeInt.ToString(), out parser)); // false

        Console.WriteLine(int.TryParse(iDontWantThisToBeInt.ToString(), out parser)); // true, even if I don't want this to be int

        Console.WriteLine(int.TryParse("3.1415", out  parser)); // false

        Console.WriteLine(int.TryParse("3.0000", out parser)); // false

        Console.WriteLine(int.TryParse("3", out parser)); // true

        Console.ReadKey();

答案 12 :(得分:0)

您可以简单地将 double 与具有相同值的 int 类型转换进行比较。

double d = 5.0m;

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

答案 13 :(得分:-2)

也许不是最优雅的解决方案,但如果你不太挑剔它就有效!

bool IsInteger(double num) {
    return !num.ToString("0.################").Contains(".");
}

答案 14 :(得分:-2)

你可以使用&#39; TryParse&#39;方法

int.TryParse()

检查该值是否可以转换为整数整数值。然后,结果可以指示可以在代码中的其他位置使用的标志。

答案 15 :(得分:-2)

试试这个:

number == Convert.ToInt16(number);