
부동소수점이슈 부터 짚고 넘어가보자.
다음 double의 비교는 실패한다.

이러한 부동소수점에 대한 이슈는 아래 영상에서도 재밌게 설명하고 있으니 나중에 참고하자.
https://www.youtube.com/watch?v=1qbZ7s9DFq8
BigDecimal.. 이름 그대로 큰 수를 잘 처리할것 같다.
그런데 다음과 같이 비교 해보면 똑같이 실패한다.

레퍼런스를 읽어보면 다음과 같이 문자열로 초기화 하거나 valuOf로 초기화 하라고 설명하고 있다.
- 이 생성자의 결과는 다소 예측하기 어려울 수 있습니다.
Java에서 BigDecimal(0.1)을 새로 작성하면 0.1(스케일이 1인 스케일 없는 값)과 정확히 같은 BigDecimal이 생성될 것이라고 생각할 수 있지만 실제로는 0.1000000000000000055511151231257827021181583404541015625와 동일합니다. 이는 0.1을 정확히 2진수(또는 유한 길이의 2진수 분수)로 표현할 수 없기 때문입니다.
따라서 생성자에 전달되는 값은 겉보기와는 달리 0.1과 정확히 같지 않습니다.
- 반면에 문자열 생성자는 완벽하게 예측할 수 있습니다.
새로운 BigDecimal("0.1")을 작성하면 예상대로 0.1과 정확히 같은 BigDecimal이 생성됩니다.
따라서 일반적으로 이 생성자보다는 문자열 생성자를 사용하는 것이 좋습니다.
- 이 생성자는 정확한 변환을 제공하므로 Double.toString(double) 메서드를 사용하여 더블을 문자열로 변환한 다음 BigDecimal(String) 생성자를 사용하는 것과 동일한 결과를 제공하지 않는다는 점에 유의하세요.
이러한 결과를 얻으려면 정적 valueOf(double) 메서드를 사용하십시오.
더 자세한 BigDecimal 에 대해서는 아래 글을 참고하자.
https://velog.io/@new_wisdom/Java-BigDecimal%EA%B3%BC-%ED%95%A8%EA%BB%98%ED%95%98%EB%8A%94-%EC%95%84%EB%A7%88%EC%B0%8C%EC%9D%98-%EB%84%88%EB%93%9C%EC%A7%93
위에서 봤지만 BigDecimal은 사용성이 좋지 않다.
게다가 querydsl이나 jpa 매핑 해서 써본 분들은 아실텐데 꽤나 번거롭다.
BigDecimal은 성능도 낭비가 될거고, (문자열, 정수처리) 사용성도 좋지 않다.
그냥 double을 쓰고싶은데, 오차와 자릿수 문제가 있다.
어떻게 보느냐에 따라 문제가 아닐수도 있다고 생각한다.
하나씩 보면서 허용할만 하다고 생각되면 쓰면 된다
위에서 0.1+0.2 != 0.3 이슈가 있었다.
그러나 0.3과 0.30000000000000004 정도면 같지 않나?
double이라면 오차는 최소 10자리 이상 일 것이다.
물론 어떤 로직이냐에 따라 오차에 너그러운 정도가 다를것이다.
https://devlog-wjdrbs96.tistory.com/254 에서는 double은 15~16 자리를 넘어가면 정밀도가 떨어진다고 한다.
다음과 같이 실제로 테스트해보니 16자리까지 정상적으로 표기되다가 17자리부터 잘못 표기되었다.
정수부를 늘려도 마찬가지로 정밀도가 떨어진다.

즉 정확히 15자리라고 말하긴 어렵고 (느낌상 진수 변환 과정에서 틀어지는것 같다) 보수적으로 15자리 정도까진 정밀하게 처리하는것 같다.
하지만 15자리 정도면 일반적으로 충분한 길이 이다.
또는 단순 통계 처리를 하고 있다면, 대체로 올림, 반올림, 절삭 등의 처리를 하면 차이가 없어진다.
물론 15자리도 넘고, 반올림 올림을 하지 않았더라도 매우 근사한 값 일 것이다.
좌표로 127.0883736632023 같은 값을 처리할 것이다.
자리수가 꽤 긴데, 길수록 정확도가 높다는 특징이 있다.
https://als2019.tistory.com/15 에 따르면, 6자리는 10cm, 7자리는 1cm의 해상도라고 한다.
즉 정수 3자리 + 소수점 7자리 정도만 저장하면 1cm이내로 위치를 특정할수가 있다.
굳이 전체를 저장하는것은 (높은 해상도) 낭비이다.
멀티폴리곤 같은건 무수히 많은 좌표를 찍을 것이다.
당연하지만 BigDecimal 연산은 double,float에 비하면 오버헤드가 있을수밖에 없다.
일반적으로 double로도 은행시스템을 다룬 경험

BigDecimal과 double의 벤치마크

부족한 지식에서 정리하느라 놓친 문제가 있을수도 있겠다.
BigDecimal 을 써야하는 다른 이유가 있다면 공유해 주시면 감사하겠습니다.
좋은 글이네요. 공유해주셔서 감사합니다.