캐스팅하지 않고 double을 long으로 변환하는 방법은 무엇입니까?


191

캐스팅하지 않고 double을 long으로 변환하는 가장 좋은 방법은 무엇입니까?

예를 들면 다음과 같습니다.

double d = 394.000;
long l = (new Double(d)).longValue();
System.out.println("double=" + d + ", long=" + l);

2
당신이 두 배 작동하지 않는 확인 이상의 2 ^ 54 또는에 맞지 않는 숫자 부분 과 같이 예를 들어, 표현식, myLong == (long)(myDouble + 1)어디 myLong등호 myDouble로 평가됩니다true
Vitalii Fedorenko

이 메소드 ( Double.longValue();)는 이와 같은 배열 목록과 같은 값에서 이중 값을 갖는 경우에도 유용합니다 ArrayList<Double>. 캐스팅 오류가 발생하기 때문입니다. 나는 여기에 와서 약간 다른 문제가있는 사람을 위해 이것을 말하고 있습니다.
SARose

답변:


250

당신이 0으로 잘리는 것에 만족한다고 가정하면, 그냥 캐스트하십시오 :

double d = 1234.56;
long x = (long) d; // x = 1234

이것은 래퍼 클래스를 통과하는 것보다 빠릅니다. 더 중요한 것은 더 읽기 쉽습니다. 이제 "항상 0"이외의 반올림이 필요한 경우 약간 더 복잡한 코드가 필요합니다.


8
큰 대답-제로 부분을 향한 제 응용 프로그램에서 잘못된 것일 수 있으므로 답에서이를 강조 표시하고 내 hungover 두뇌가 캐스팅 대신 Math.round ()를 사용하도록 상기시켜주십시오.
Phantomwhale

123

... 그리고 잘리지 않는 반올림 방법은 다음과 같습니다. Java API 매뉴얼에서 찾아보기를 서두르십시오.

double d = 1234.56;
long x = Math.round(d); //1235

캐스트와 동일한 결과를 제공하지 않습니다. 부자가하고 싶은 것에 달려 있습니다.
Cyrille Ka

3
네. 그것은 Jon이 말한 것에 덧붙여서 생각되었다 :)
Johannes Schaub-litb

2
기본 유형이 아닌 Double 및 Long 객체에서도 작동하기 때문에 이것을 좋아합니다.
themanatuf

58

선호되는 접근 방식은 다음과 같습니다.

Double.valueOf(d).longValue()

로부터 더블 (자바 플랫폼 SE 7) 문서 :

Double.valueOf(d)

Double지정된 double값을 나타내는 인스턴스를 반환 합니다. 새 Double인스턴스가 필요하지 않은 경우이 메소드는 일반적으로 생성자보다 우선적으로 사용되어야합니다.이 메소드는 Double(double)자주 요청되는 값을 캐싱하여 공간 및 시간 성능이 훨씬 향상 될 수 있기 때문입니다.


36

(new Double(d)).longValue() 내부적으로 캐스트 만 수행하므로 Double 객체를 만들 이유가 없습니다.


13

Guava Math 라이브러리에는 double을 long으로 변환하기 위해 특별히 설계된 방법이 있습니다.

long DoubleMath.roundToLong(double x, RoundingMode mode)

java.math.RoundingMode반올림 동작을 지정하는 데 사용할 수 있습니다 .


7

DOUBLE이 실제로 LONG이라는 강한 의혹이 있고

1) EXACT 값을 LONG으로 처리하십시오.

2) LONG이 아닌 경우 오류 발생

다음과 같이 시도해보십시오.

public class NumberUtils {

    /**
    * Convert a {@link Double} to a {@link Long}.
    * Method is for {@link Double}s that are actually {@link Long}s and we just
    * want to get a handle on it as one.
    */
    public static long getDoubleAsLong(double specifiedNumber) {
        Assert.isTrue(NumberUtils.isWhole(specifiedNumber));
        Assert.isTrue(specifiedNumber <= Long.MAX_VALUE && specifiedNumber >= Long.MIN_VALUE);
        // we already know its whole and in the Long range
        return Double.valueOf(specifiedNumber).longValue();
    }

    public static boolean isWhole(double specifiedNumber) {
        // http://stackoverflow.com/questions/15963895/how-to-check-if-a-double-value-has-no-decimal-part
        return (specifiedNumber % 1 == 0);
    }
}

Long은 Double의 하위 집합이므로 무의식적으로 Long 범위를 벗어난 Double을 변환하려고하면 이상한 결과가 발생할 수 있습니다.

@Test
public void test() throws Exception {
    // Confirm that LONG is a subset of DOUBLE, so numbers outside of the range can be problematic
    Assert.isTrue(Long.MAX_VALUE < Double.MAX_VALUE);
    Assert.isTrue(Long.MIN_VALUE > -Double.MAX_VALUE); // Not Double.MIN_VALUE => read the Javadocs, Double.MIN_VALUE is the smallest POSITIVE double, not the bottom of the range of values that Double can possible be

    // Double.longValue() failure due to being out of range => results are the same even though I minus ten
    System.out.println("Double.valueOf(Double.MAX_VALUE).longValue(): " + Double.valueOf(Double.MAX_VALUE).longValue());
    System.out.println("Double.valueOf(Double.MAX_VALUE - 10).longValue(): " + Double.valueOf(Double.MAX_VALUE - 10).longValue());

    // casting failure due to being out of range => results are the same even though I minus ten
    System.out.println("(long) Double.valueOf(Double.MAX_VALUE): " + (long) Double.valueOf(Double.MAX_VALUE).doubleValue());
    System.out.println("(long) Double.valueOf(Double.MAX_VALUE - 10).longValue(): " + (long) Double.valueOf(Double.MAX_VALUE - 10).doubleValue());
}

Long is a subset of Double정확하지 않습니다. Long의 유효 자릿수는 Double보다 크므로 Long이 보유한 일부 정보는 Double로 변환 될 때 유실 될 수 있습니다. 예 = tio.run/…
Thariq Nugrohotomo

4

당신은 이진 변환을 원하십니까

double result = Double.longBitsToDouble(394.000d);

2
이것은 요구되는 것과 반대입니다.
Lucas Phillips

@LucasPhillips 당신이 맞아요. 나는 그 질문을 잘못 읽었어야하지만, 다른 사람들을 도울 수 있기 때문에 대답을 남길 것입니다.
pvorb

1

간단히 다음과 같이

double d = 394.000;
long l = d * 1L;

0

간단히 말해서 Double 객체를 만드는 것보다 캐스팅이 더 효율적입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.