2023.11.28(화) TIL

quinones·2023년 11월 28일

오늘은 2주차 과제인 계산기를 만들어보는 시간을 가졌다.
만드는 도중 오늘 마주한 문제는 부동소수점 오류였다.

double형 실수가 두개 주어지고, 두개의 실수를 더한다고 생각해보면

fun main() {
    var a = 0.1
    var b = 0.2
    var result = a+b
    print(result)
}

여기서 예상하는 결과값은? 당연히 0.3이였다. 하지만..

이런 결과값이 나왔다..

이유를 찾아봤다.
만약 컴퓨터에 5라는 숫자를 저장한다 -> 컴퓨터는 Ram에 이 수를 저장하는데 컴퓨터는 이 5라는 숫자를 2진수로 저장한다. 그러면 0101이라고 저장하게 된다.

같은 원리로 0.125같은 숫자를 2진법으로 변환하게되면 0.001로 깔끔하게 떨어지지만 0.1같은 수를 2진법으로 변환하게되면 0.00011001100110011...와 같이 무한히 반복된다.
그래서 컴퓨터는 뒷부분을 자르고 저장해주는데, 이때 아주 약간의 오차가 생기게 되는것이다.

그렇다는건

var a = 0.1

이런 코드는 a에 0.1을 저장한게 아니고, 0.1과 아주 비슷한 숫자를 저장했다고 생각하면 된다.

그렇다면! 0.1과 0.2를 더한 값인 0.3을 제대로 나오게 하는 방법은BigDecimal을 이용하는 방법이다. 이는 속도가 느리고 기본타입보다 사용법이 불편하다는 단점이 존재하지만, 숫자를 정밀하게 저장하고 표현할수 있다는 장점이 있다. 사용법은 간단했다.

import java.math.BigDecimal
fun main() {
    var a = BigDecimal("0.1")
    var b = BigDecimal("0.2")
    var result = a+b
    print(result)
}

BigDecimal을 import시켜주고, 원하는 값을String형태로 BigDecimal에 넣어주면 원하는 값이 나온다.
정수가아닌 실수형자료를 사칙연산 해줄때 원하는 값이 안나온다면, 생각해봐야하는 문제일것 같다.

profile
이우진

0개의 댓글