如何测试双精度数是否为整数


165

是否有可能做到这一点?

double variable;
variable = 5;
/* the below should return true, since 5 is an int. 
if variable were to equal 5.7, then it would return false. */
if(variable == int) {
    //do stuff
}

我知道代码可能不会去这样的事情,但怎么去了?



1
您将从中得到什么? double并且int在内存中的表示方式有所不同,您将根据内存处理的上下文使用一个或另一个。
Makoto 2012年

@Legend,我会按照您的建议进行操作;您是否偶然知道%1如何将效率与其他用户建议的Math.floor(变量)进行比较?
G. Bach 2012年

3
@Makoto这是一个寻找pygatorean三元组的程序。平方根有时可以加倍,但同时有时也可以是整数。你明白我的意思吗?
JXPheonix 2012年

@JXPheonix:所以值可以是浮点值或整数值。说得通。
Makoto 2012年

Answers:


146
if ((variable == Math.floor(variable)) && !Double.isInfinite(variable)) {
    // integer type
}

这将检查双精度值的四舍五入值是否与双精度值相同。

您的变量可能具有int或double值,并且Math.floor(variable)始终具有int值,因此,如果您的变量等于,Math.floor(variable)则它必须具有int值。

如果变量的值是无穷大或负无穷大,那么这也不起作用,因此将“只要变量不是无穷大”添加到条件中。


3
“如果自变量是NaN或无穷大或正零或负零,则结果与自变量相同。” docs.oracle.com/javase/6/docs/api/java/lang/...
蒂姆Schmelter

2
@TimSchmelter:好收获。还值得注意的是,NaN不等于任何值(包括其自身),但+/- Inf等于其自身-因此,存在两种边缘情况!
maerics 2012年

Skon和Fouad都发布了更好的答案。
乔尔·克里斯托

@JoelChristophel:我不同意。这是一个好方法,因为它消除了类型溢出的风险。我唯一不喜欢的是断言,int如果if计算结果为,则变量为an true
Bathsheba,2015年

@Bathsheba(Double.POSITIVE_INFINITY%1)== 0,并且其否定值都为false。
乔尔·克里斯托

222

或者,您可以使用模运算符:

(d % 1) == 0


2
我真的很喜欢这种解决方案的简单性。它既易于阅读又易于实现。
krispy 2014年

1
非常直观的解决方案
Daniel San

3
在计算方面,它快于Math.rint(d)吗?
iTurki

2
是的,这很好,但是请注意,这是一个Java解决方案,并且d在C和C ++中没有明确定义为否定。
Bathsheba,2015年

4
在Sonar中,这会产生一个问题“不应使用浮点值进行相等性测试”。
Julio D

86

番石榴:DoubleMath.isMathematicalInteger。(公开:我写的。)或者,如果您还没有导入Guava,那x == Math.rint(x)是最快的方法。rintfloor或快得多ceil


3
不知道Math.rint您是正确的。它比Math.floor快得多
Lenny Markus

这在某种程度上比Eng.Fouad的演员表更好吗?
乔尔·克里斯托

@JoelChristophel:是的。并非所有具有整数值的双精度值都在int或更长的范围内,因此该测试无法对其进行。
Louis Wasserman

知道了 然后(d%1)== 0仍然有效。
乔尔·克里斯托


6

试试这个

public static boolean isInteger(double number){
    return Math.ceil(number) == Math.floor(number); 
}

例如:

Math.ceil(12.9) = 13; Math.floor(12.9) = 12;

因此12.9整数,不过

 Math.ceil(12.0) = 12; Math.floor(12.0) =12; 

因此12.0是整数


3

这是一个版本 IntegerDouble

    private static boolean isInteger(Double variable) {
    if (    variable.equals(Math.floor(variable)) && 
            !Double.isInfinite(variable)          &&
            !Double.isNaN(variable)               &&
            variable <= Integer.MAX_VALUE         &&
            variable >= Integer.MIN_VALUE) {
        return true;
    } else {
        return false;
    }
}

转换DoubleInteger

Integer intVariable = variable.intValue();

3

考虑:

Double.isFinite (value) && Double.compare (value, StrictMath.rint (value)) == 0

这坚持使用Java核心语言,并避免了浮点值(==)之间的相等比较,这被认为是不好的。该isFinite()所必需rint()将直通无穷大值。



3

这是一个很好的解决方案:

if (variable == (int)variable) {
    //logic
}

为什么(bool)投?
xdavidliu

1
@xdavidliu不需要那样。我们可以忽略它。
Nitish

2

与上面的SkonJeet的答案类似,但是性能更好(至少在Java中):

Double zero = 0d;    
zero.longValue() == zero.doubleValue()

1
public static boolean isInteger(double d) {
  // Note that Double.NaN is not equal to anything, even itself.
  return (d == Math.floor(d)) && !Double.isInfinite(d);
}

一个更正确的实现将返回false,并且您将不得不编写另一个将int作为参数并返回true的方法。:D
阿尔法

0

您可以通过以下方式尝试:获取double的整数值,从原始double值中减去该值,定义一个舍入范围,并测试新double值的绝对数(不带整数部分)是否大于或小于您的double定义范围。如果较小,则可以认为它是整数值。例:

public final double testRange = 0.2;

public static boolean doubleIsInteger(double d){
    int i = (int)d;
    double abs = Math.abs(d-i);
    return abs <= testRange;
}

如果将值33.15分配给d,则该方法返回true。为了获得更好的结果,您可以自行决定为testRange分配较低的值(0.0002)。


0

就个人而言,我更喜欢简单的模运算解决方案。不幸的是,SonarQube不喜欢在没有设置舍入精度的情况下使用浮点进行相等性测试。因此,我们试图找到一种更合规的解决方案。这里是:

if (new BigDecimal(decimalValue).remainder(new BigDecimal(1)).equals(BigDecimal.ZERO)) {
    // no decimal places
} else {
    // decimal places
}

Remainder(BigDecimal)返回BigDecimal值为的(this % divisor)。如果这个等于零,我们就知道没有浮点数。


0

我的简单解决方案:

private boolean checkIfInt(double 
 value){
 return value - Math.floor(value) == 0;
 }

-1

这是一个解决方案:

float var = Your_Value;
if ((var - Math.floor(var)) == 0.0f)
{
    // var is an integer, so do stuff
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.