Java가 부동 소수점 연산을 구현하는 데 IEEE 754 표준을 사용하는 경우 관심이 있습니다.
IEEE-754 여러 부동 소수점 유형에 대한 표준을 정의합니다. 수년 동안 그들은 모두 이진 부동 소수점이었습니다. Java의 float
과 double
은 다음과 같습니다. float
은 32 비트 IEEE-754 2 진 부동 소수점 값 (표준에서 binary32
)을 나타냅니다. double
은 64 비트 코드입니다 (표준 코드 binary64
). 이 2 진 부동 소수점 수는 컴퓨터에서 계산하는 것이 매우 효율적이지만 이진수로 작업하고 10 진수로 작업하기 때문에 몇 가지 기대 불일치가 있습니다. 예를 들어 0.1
은 double
에 정확하게 저장할 수 없으며 0.1 + 0.2
은 기발한 것으로 나타났습니다 (0.30000000000000004
). 자세한 내용은 Is floating point math broken?을 참조하십시오. 예를 들어 재무 계산에 좋은 선택은 아닙니다.
BigDecimal
은 십진수 부동 소수점을 구현하는 Java 클래스입니다. double
을 사용하는 것보다 훨씬 느리지 만 결과는 소수점 기대에 맞습니다 (예 : 0.1 + 0.2
은 0.3
).
IEEE-754의 2008 버전에는 중요한 새로운 형식, 특히 decimal32
, decimal64
및 decimal128
이 추가되었습니다. 이들은 십진수 부동 소수점이므로 우리와 같은 방식으로 작동합니다. 0.1
은 decimal64
에 정확하게 저장할 수 있습니다. 0.1 + 0.2
은 decimal64
에 0.3
입니다. 그러나, 내가 말할 수있는 한, 그들은 당신의 질문에 정말로 관련이 없습니다.
BigDecimal
은 IEEE-754 2008보다 약간 앞선 것으로 (일부 마진을 기준으로) 자체의 의미를 정의합니다.
그리고 만약 수학 클래스에서 IEEE 754 표준을 사용하는 것이 아니라면? ,
JDK9는 IEEE-754 2008 사양 (A fused multiply-add 않는 등 fma
)에 의해 정의 된 일을 Math
에 새로운 작업을 추가하고, 그래서 그것은 IEEE-754 2008 스펙을 참조하여 그 작업을 정의 명확성을 위해.
더 읽기 :
Nitpick : 이진 부동 소수점 형식뿐만 아니라, 소수점 부동을 정의, IEEE 754-2008, 대한 애 스커 문의 '0.1'를 정확하게 표현할 수있는'decimal64'와'decimal128' 포인트 타입입니다. – njuffa
@njuffa : 좋은 점, 나는 질문의 인용 된 비트에서 그것을 놓쳤다. 그리고 블라인드 링크는 2008 표준에 대해 말하는 JDK9 사양과 관련이 있습니다. 그것은 완전히 대답을 바꿉니다. –
@njuffa : 고정되어 있으며 다시 지적 해 주셔서 감사합니다. –