如何判断小数或双精度值是否为整数?
例如:
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")
输出值。 如果没有小数点值,那么我不想显示它。
对于浮点数,
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)
有多种方法可以做到这一点。 例如:
double d = 5.0;
bool isInt = d == (int)d;
您也可以使用模数。
double d = 5.0;
bool isInt = d % 1 == 0;
这个怎么样?
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);
}
bool IsInteger(double num) {
if (ceil(num) == num && floor(num) == num)
return true;
else
return false;
}
编辑:Mark Rushakoff Pwned。
虽然所提出的解决方案似乎适用于简单的示例,但通常这样做是一个坏主意。数字可能不完全是整数,但当您尝试格式化它时,它足够接近整数,您会得到
相反,首先对其进行格式化,如果您的字符串以句点结尾,后跟零,则将其删除。还有一些格式可以自动去除尾随零。这可能足以满足您的目的。
double d = 1.0002;
Console.WriteLine(d.ToString("0.##"));
d = 1.02;
Console.WriteLine(d.ToString("0.##"));
输出:
1
1.02
.NET 7 现在为此提供了内置方法:
decimal.IsInteger
double.IsInteger
static bool IsWholeNumber(double x)
{
return Math.Abs(x % 1) < double.Epsilon;
}
bool isInteger = (double)((int)f) == f ;
和
bool isInteger = (decimal)((int)d) == d ;
如果您想要两种类型的单个表达式,也许
bool isInteger = (double)((int)val) == (double)val ;
如果
public bool IsInt32(double value)
{
return value >= int.MinValue && value <= int.MaxValue && value == (int)value;
}
您可以对双精度类型使用字符串格式。这是一个例子: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"
如果这没有帮助,请告诉我。
public static bool isInteger(decimal n)
{
return n - (Int64)n == 0;
}
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.使用 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();
您可以简单地将 double 与相同值的 int 转换进行比较。
double d = 5.0m;
if (d == (int)d)
{
....
}
这是我解决这个问题的方法。 也许有人会有用。
public static bool IsInt(object number, int? decimalPlaces = null)
{
bool isInt;
var splinted = number.ToString().Split(',');
if (splinted.Length == 1)
isInt = true;
else
{
var charsAfterComma = decimalPlaces != null ? splinted[1].Substring(0, (int) decimalPlaces) : splinted[1];
isInt = charsAfterComma.First().ToString() == "0" && charsAfterComma.Replace("0", "") == "";
}
return isInt;
}
最好的方法是使用内置的静态方法而不是任何其他答案:
double.IsInteger(4.5) // false
试试这个:
number == Convert.ToInt16(number);
也许不是最优雅的解决方案,但如果你不太挑剔的话它是可行的!
bool IsInteger(double num) {
return !num.ToString("0.################").Contains(".");
}