double이 정수인지 테스트하는 방법


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
C #하지만 자바에서 유사한 stackoverflow.com/a/4077262/284240 ( 는 Integer.MAX_VALUE )
팀 Schmelter

1
이것으로부터 무엇을 얻을 것입니까? doubleint다르게 메모리에 표시됩니다, 당신은 하나 또는 메모리 처리의 문맥에 따라 다른 사용할 수 있습니다.
Makoto

@Legend, 나는 당신이 제안한 것과 똑같이했을 것입니다. 우연히 % 1이 다른 사용자가 제안한 Math.floor (variable)와 효율성을 어떻게 비교하는지 알고 있습니까?
G. Bach

3
@Makoto 그것은 pygatorean 트리플을 찾는 프로그램입니다. 제곱근은 때때로 두 배가 될 수 있지만, 동시에 때때로 개입 할 수도 있습니다. 무슨 말인지 알 겠어?
JXPheonix

@JXPheonix : 따라서 값은 부동 소수점 값 또는 정수 값일 수 있습니다. 말이된다.
Makoto

답변:


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

double의 반올림 값이 double과 같은지 확인합니다.

변수는 int 또는 double 값을 가질 수 있고 Math.floor(variable)항상 int 값을 가질 수 있으므로 변수가 같으면 Math.floor(variable)int 값을 가져야합니다.

변수의 값이 무한 또는 음의 무한대 인 경우에도 작동하지 않으므로 조건에 '변수가 무한대가 아닌 한'을 추가하십시오.


3
"인수가 NaN이거나 무한대 또는 양의 0 또는 음의 0이면 결과는 인수와 같습니다." docs.oracle.com/javase/6/docs/api/java/lang/…
Tim Schmelter

2
@ TimSchmelter : 잘 잡습니다. NaN은 (자체를 포함하여) 다른 것과 같지 않지만 +/- Inf는 자신과 같습니다. 따라서 두 가지 경우가 있습니다!
매 릭스

Skon과 Fouad는 훨씬 더 나은 답변을 게시했습니다.
Joel Christophel

@JoelChristophel : 동의하지 않습니다. 유형 오버플로의 위험을 제거하므로 좋은 방법입니다. 내가 좋아하지 않는 유일한 것은 변수가 있다는 주장이었다 int은 if if평가됩니다에 true.
바스 셰바

@Bathsheba (Double.POSITIVE_INFINITY % 1) == 0 및 해당 음수는 모두 false로 평가됩니다.
Joel Christophel

222

또는 모듈로 연산자를 사용할 수 있습니다.

(d % 1) == 0


2
나는이 솔루션의 단순성을 정말 좋아합니다. 읽고 쉽게 구현할 수 있습니다.
krispy

1
매우 직관적 인 솔루션
Daniel San

3
계산 측면에서 볼 때보 다 빠릅니다 Math.rint(d).
iTurki

2
예, 이것은 훌륭하지만 Java 솔루션이며 dC 및 C ++에서 부정적 으로 잘 정의되어 있지 않습니다 .
Bathsheba

4
Sonar에서는 "부동 소수점 값으로 평등 테스트를 수행해서는 안됩니다"라는 문제가 발생합니다.
Julio D

86

구아바 : DoubleMath.isMathematicalInteger. (공개 : 내가 썼습니다.) 또는 구아바를 아직 수입하지 않은 경우 x == Math.rint(x)가장 빠른 방법입니다. 또는 rint보다 빠릅니다 .floorceil


3
Math.rint에 대해 몰랐습니다. Math.floor보다 훨씬 빠릅니다
Lenny Markus

이것이 Eng.Fouad의 캐스팅 예제보다 선호됩니까?
Joel Christophel

@JoelChristophel : 예. 정수 값을 가진 모든 double이 int 또는 long 범위에있는 것은 아니므로 테스트가 작동하지 않습니다.
Louis Wasserman

알았어 그런 다음 (d % 1) == 0은 여전히 ​​유효합니다.
Joel Christophel

20
public static boolean isInt(double d)
{
    return d == (int) d;
}

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

Integer와에 대한 버전은 다음 과 Double같습니다.

    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;
    }
}

로 변환 Double하려면 Integer:

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
alfa

0

당신은 이런 식으로 시도 할 수 있습니다 : 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;
}

d에 값 33.15를 지정하면 메소드는 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이면 부동 소수점이 없다는 것을 알 수 있습니다.



-1

해결책은 다음과 같습니다.

float var = Your_Value;
if ((var - Math.floor(var)) == 0.0f)
{
    // var is an integer, so do stuff
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.