BigDecimal을 정수로 변환


134

BigDecimal을 반환하는 최대 절전 모드 메서드가 있습니다. 해당 번호를 전달 해야하는 다른 API 메소드가 있지만 Integer를 매개 변수로 허용합니다. 두 메소드의 리턴 유형 또는 변수 유형을 변경할 수 없습니다.

이제 BigDecimal을 Integer로 변환하고 두 번째 방법으로 전달하는 방법은 무엇입니까?

이 방법이 있습니까?


6
제목을 수정했습니다. 이다 전환 되지 캐스팅.
Lorne의 후작

답변:


209

당신은 myBigDecimal.intValueExact()(또는 그냥 intValue()) 전화 하고 정보를 잃을 경우 예외를 던질 것입니다. 그것은 int를 반환하지만 autoboxing은 그것을 처리합니다.


1
intValueExact()좋은 추천입니다. 그것은 1.5
Anon

intValue()숫자가 Integer범위 내에 있다고 긍정적으로 생각하면 100 % 베팅하지 않는 한 전화하는 것은 위험 합니다.
Snekse

1
"Integer.valueOf (myBigDecimal.intValueExact ())"가 의미가 있습니까?
OddDev

32

BigDecimal보다 큰 값을 포함하지 않을 것이라고 보장 할 수 있습니까 Integer.MAX_VALUE?

그렇다면 코드 호출은 intValue다음과 같습니다.

Integer.valueOf(bdValue.intValue())

예.
Integer

2
프리미티브 권한 대신 Object를 얻는 것 외에 valueOf를 수행 할 이유가 없습니까?
바질

나는 이것이 공식적인 대답이어야한다고 말하고 싶습니다. 한계를 언급 b. 오토 박싱을 방지합니다.
ledlogic

22

TL; DR

보편적 인 전환 요구를 위해 이들 중 하나를 사용하십시오

//Java 7 or below
bigDecimal.setScale(0, RoundingMode.DOWN).intValueExact()
//Java 8    
bigDecimal.toBigInteger().intValueExact()

추리

대답은 요구 사항이 무엇이며 이러한 질문에 어떻게 대답 하느냐에 달려 있습니다.

  • 는 것이다 BigDecimal잠재적으로 비 제로 소수 부분이 있습니까?
  • 는 것이다 BigDecimal잠재적에 맞지 Integer범위?
  • 0이 아닌 소수 부분을 둥글거나 잘게 하시겠습니까?
  • 0이 아닌 분수 부분은 어떻게 반올림 하시겠습니까?

처음 두 가지 질문에 대답하지 않으면 BigDecimal.intValueExact()다른 사람들이 제안한대로 사용 하고 예상치 못한 일이 발생했을 때 터질 수 있습니다.

2 번 문제에 대해 100 % 확신이 없다면, 항상 정답 intValue()아닙니다 .

더 나은 만들기

다른 답변을 기반으로 다음 가정을 사용합시다.

  • 우리는 정밀도를 잃고 값을 자르는 것으로 괜찮습니다. 그것이 intValueExact()자동 권투 기능 이기 때문입니다.
  • 상위 비트를 떨어 뜨릴 때 발생하는 랩을 매우 구체적으로 필요로하지 않는 한 다른 것이 미친 것이기 때문에 범위 BigDecimal보다 큰 경우 예외가 발생합니다 Integer.

이러한 매개 변수가 주어지면 intValueExact()소수 부분이 0이 아닌 경우 원하지 않는 경우 예외가 발생합니다. 반면에 intValue()우리 BigDecimal가 너무 클 경우 예외를 던지지 마십시오 .

두 세계를 모두 활용하려면 BigDecimal첫 번째를 반올림 한 다음 변환하십시오. 또한 반올림 프로세스를보다 효과적으로 제어 할 수 있다는 이점이 있습니다.

스팍 그루비 테스트

void 'test BigDecimal rounding'() {
    given:
    BigDecimal decimal = new BigDecimal(Integer.MAX_VALUE - 1.99)
    BigDecimal hugeDecimal = new BigDecimal(Integer.MAX_VALUE + 1.99)
    BigDecimal reallyHuge = new BigDecimal("10000000000000000000000000000000000000000000000")
    String decimalAsBigIntString = decimal.toBigInteger().toString()
    String hugeDecimalAsBigIntString = hugeDecimal.toBigInteger().toString()
    String reallyHugeAsBigIntString = reallyHuge.toBigInteger().toString()

    expect: 'decimals that can be truncated within Integer range to do so without exception'
    //GOOD: Truncates without exception
    '' + decimal.intValue() == decimalAsBigIntString
    //BAD: Throws ArithmeticException 'Non-zero decimal digits' because we lose information
    // decimal.intValueExact() == decimalAsBigIntString
    //GOOD: Truncates without exception
    '' + decimal.setScale(0, RoundingMode.DOWN).intValueExact() == decimalAsBigIntString

    and: 'truncated decimal that cannot be truncated within Integer range throw conversionOverflow exception'
    //BAD: hugeDecimal.intValue() is -2147483648 instead of 2147483648
    //'' + hugeDecimal.intValue() == hugeDecimalAsBigIntString
    //BAD: Throws ArithmeticException 'Non-zero decimal digits' because we lose information
    //'' + hugeDecimal.intValueExact() == hugeDecimalAsBigIntString
    //GOOD: Throws conversionOverflow ArithmeticException because to large
    //'' + hugeDecimal.setScale(0, RoundingMode.DOWN).intValueExact() == hugeDecimalAsBigIntString

    and: 'truncated decimal that cannot be truncated within Integer range throw conversionOverflow exception'
    //BAD: hugeDecimal.intValue() is 0
    //'' + reallyHuge.intValue() == reallyHugeAsBigIntString
    //GOOD: Throws conversionOverflow ArithmeticException because to large
    //'' + reallyHuge.intValueExact() == reallyHugeAsBigIntString
    //GOOD: Throws conversionOverflow ArithmeticException because to large
    //'' + reallyHuge.setScale(0, RoundingMode.DOWN).intValueExact() == reallyHugeAsBigIntString

    and: 'if using Java 8, BigInteger has intValueExact() just like BigDecimal'
    //decimal.toBigInteger().intValueExact() == decimal.setScale(0, RoundingMode.DOWN).intValueExact()
}

18

글쎄, 당신은 전화 할 수 있습니다 BigDecimal.intValue():

이 BigDecimal를 정수로 변환합니다. 이 변환은 Java 언어 사양에 정의 된대로 double에서 short로 좁히는 기본 변환과 유사합니다.이 BigDecimal의 소수 부분은 모두 버리고 결과 "BigInteger"가 int에 맞지 않을 경우에는 낮음 32 비트가 반환됩니다. 이 변환은이 BigDecimal 값의 전체 크기와 정밀도에 대한 정보를 잃을 수 있으며 반대 부호와 함께 결과를 리턴 할 수 있습니다.

Integer.valueOf(int)최신 버전의 Java를 사용하는 경우 명시 적으로 전화를 걸 거나 자동 박싱 기능을 사용할 수 있습니다.





-4

위의 내용이 저에게 효과적이지 않다는 것을 알았습니다. JTable에서 셀 값을 가져 왔지만 double 또는 int 등으로 캐스팅 할 수 없었습니다. 내 솔루션 :

Object obj = getTable().getValueAt(row, 0);

여기서 행 0은 항상 숫자입니다. 이것이 여전히 스크롤하는 데 도움이되기를 바랍니다!

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