캐스팅 없이 더블을 롱으로 변환하려면 어떻게 해야 하나요?
캐스팅 없이 더블을 롱으로 변환하는 가장 좋은 방법은 무엇입니까?
예를 들어 다음과 같습니다.
double d = 394.000;
long l = (new Double(d)).longValue();
System.out.println("double=" + d + ", long=" + l);
0을 향해 잘라내는 데 만족한다고 가정하면 다음과 같이 캐스팅할 수 있습니다.
double d = 1234.56;
long x = (long) d; // x = 1234
이것은 래퍼 클래스를 통과하는 것보다 더 빠릅니다.그리고 더 중요한 것은 읽기 쉽다는 것입니다."항상 0을 향해" 이외의 반올림이 필요한 경우 조금 더 복잡한 코드가 필요합니다.
그리고 여기 잘리지 않는 반올림 방법이 있습니다.Java API Manual에서 서둘러 검색:
double d = 1234.56;
long x = Math.round(d); //1235
바람직한 접근법은 다음과 같다.
Double.valueOf(d).longValue()
Double (Java Platform SE 7) 매뉴얼에서 다음 절차를 수행합니다.
Double.valueOf(d)
a를 반환한다.
Double지정된 인스턴스를 나타냅니다.double값. 만약 새로운 경우Double인스턴스는 필요하지 않습니다. 일반적으로 이 메서드는 생성자보다 우선하여 사용해야 합니다.Double(double)이 방법은 자주 요청하는 값을 캐시함으로써 공간 및 시간 성능이 크게 향상될 가능성이 높기 때문입니다.
(new Double(d)).longValue()내부적으로 캐스팅만 하기 때문에 Double 객체를 만들 필요가 없습니다.
Guava Math 라이브러리는 배수를 long으로 변환하기 위해 특별히 설계된 방법이 있습니다.
long DoubleMath.roundToLong(double x, RoundingMode mode)
사용할 수 있습니다.java.math.RoundingMode반올림 동작을 지정합니다.
DUBLE이 실제로는 LONG이라고 강하게 의심하고 있는 경우,
1) EXCRUCT 값을 LONG으로 처리
2) 길이가 길지 않은 경우 오류를 발생시킵니다.
다음과 같은 작업을 수행할 수 있습니다.
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());
}
간단히 말하면 다음과 같습니다.
double d = 394.000;
long l = d * 1L;
간단히 말해서, 캐스팅은 이중 객체를 만드는 것보다 더 효율적입니다.
언급URL : https://stackoverflow.com/questions/321549/how-to-convert-a-double-to-long-without-casting
'programing' 카테고리의 다른 글
| 유닛 테스트 C 코드 (0) | 2022.07.23 |
|---|---|
| 구성 요소가 여러 번 로드되면 eventBus가 중복 이벤트를 수신합니다. (0) | 2022.07.23 |
| "!!"는 C로 뭐죠? (0) | 2022.07.23 |
| 파라미터로서의 Java Pass 메서드 (0) | 2022.07.23 |
| Vue js;Vue 라우터가 단순 경로에서 생성자 오류가 아닙니다. (0) | 2022.07.23 |