How to determine if a decimal/double is an integer?
如何判断一个十进制或双精度值是一个整数?
例如:
1 2 | decimal d = 5.0; // Would be true decimal f = 5.5; // Would be false |
或
1 2 | double d = 5.0; // Would be true double f = 5.5; // Would be false |
我之所以想知道这一点,是因为我可以通过编程确定是否要使用
对于浮点数,
1 2 3 4 5 6 7 | public static void Main (string[] args) { decimal d = 3.1M; Console.WriteLine((d % 1) == 0); d = 3.0M; Console.WriteLine((d % 1) == 0); } |
输出:
1 2 | False True |
更新:正如下面提到的@adrian lopez,与一个小值
1 | Math.Abs(d % 1) <= (Double.Epsilon * 100) |
有很多方法可以做到这一点。例如:
1 2 | double d = 5.0; bool isInt = d == (int)d; |
您也可以使用modulo。
1 2 | double d = 5.0; bool isInt = d % 1 == 0; |
这个怎么样?
1 2 3 | public static bool IsInteger(double number) { return number == Math.Truncate(number); } |
同一代码用于
马克·拜尔斯说得很好,事实上:这可能不是你真正想要的。如果您真正关心的是一个四舍五入到小数点后两位的数字是否为整数,您可以这样做:
1 2 3 | public static bool IsNearlyInteger(double number) { return Math.Round(number, 2) == Math.Round(number); } |
虽然所提出的解决方案似乎适用于简单的例子,但一般来说,这样做是一个坏主意。一个数字可能不是一个整数,但当您试图格式化它时,它已经足够接近一个整数,您可以得到
相反,首先格式化它,如果字符串以一个后跟零的句点结束,那么去掉它们。还有一些格式,您可以使用该条带自动尾随零。这对你来说也许足够好。
1 2 3 4 | double d = 1.0002; Console.WriteLine(d.ToString("0.##")); d = 1.02; Console.WriteLine(d.ToString("0.##")); |
输出:
1 2 | 1 1.02 |
1 2 3 4 5 6 | bool IsInteger(double num) { if (ceil(num) == num && floor(num) == num) return true; else return false; } |
问题解答
编辑:马克·拉沙科夫编辑。
如果
1 2 3 4 | public bool IsInt32(double value) { return value >= int.MinValue && value <= int.MaxValue && value == (int)value; } |
1 2 3 4 | static bool IsWholeNumber(double x) { return Math.Abs(x % 1) < double.Epsilon; } |
Mark Rushakoff的回答可能更简单,但由于没有隐式的除法运算,因此以下内容也有效,而且效率可能更高:
1 | bool isInteger = (double)((int)f) == f ; |
和
1 | bool isInteger = (decimal)((int)d) == d ; |
如果两种类型都需要一个表达式,也许
1 | bool isInteger = (double)((int)val) == (double)val ; |
您可以对双精度类型使用字符串格式。下面是一个例子:
1 2 3 4 5 6 7 8 9 10 11 | 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" |
如果这不起作用,请告诉我。
1 2 3 4 | public static bool isInteger(decimal n) { return n - (Int64)n == 0; } |
使用Int.Tryparse将产生以下结果:var应等于3;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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(); |
我也遇到过类似的情况,但是值是字符串。用户输入的值应该是一个美元金额,所以我想验证它是否是数字,并且最多有两个小数位。
下面是我的代码,如果字符串"s"表示最多有两位小数的数字,则返回true,否则返回false。它避免了由于浮点值不精确而导致的任何问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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-if-numeric-value-has.html上更详细地讨论了这个问题。
试试这个:
1 | number == Convert.ToInt16(number); |
你可以使用"台盼色"方法。
1 | int.TryParse() |
这将检查该值是否可以转换为整数整数值。然后,结果可以指示一个标志,该标志可以在代码中的其他地方使用。
也许不是最优雅的解决方案,但如果你不太挑剔,它是有效的!
1 2 3 | bool IsInteger(double num) { return !num.ToString("0.################").Contains("."); } |