코드 최적화 중에 문득 궁금해진 것
부동 소수점 값 비교 시에 사용할 수 있는 방법이 꽤 다양한데 뭐가 더 나을까?
※ 부동 소수점 오차 때문에 정확한 비교 필요
-> A * B = 10f가 나오는 게 맞다고 보여도,
10f가 실제로 9.999999f 라는 등 오차가 생기는 경우가 있다
(IEEE-754 표준법 사용해서 저장하기 때문에 지수 표현에 오차가 생기는 것)
그래서 정확한 비교를 위한 대표적인 방법 두 가지.
이 둘 중에 뭘 사용하는 게 나을까?라는 멍청한 생각을 가지고 가볍게 시작했다.
결론은 일단 당연히 케바케
Mathf.Approximately
Mathf의 구현 방식을 보면
단순 비교가 아니라 두 수가 0의 근사치일 때도 잘 동작하도록 구현돼있다.
또한 Epslion을 여기서 사용하는데 8을 곱해줌으로 허용 범위를 널널하게 잡은듯 싶다.
Mathf.Epsilon 과 float.Epsilon
근데 문서에는 Epsilon보다 작은 범위 내의 오차를 잡아준다고 돼있는데
이러면 Epsilon * 8 보다 작은 범위 내의 오차를 잡아준다고 적어놔야 되는 거 아닌가?
혹시 Mathf의 Epsilon과 float.Epsilon이 다르니까 그렇겠지라고 생각한다면
Mathf의 Epsilon을 타고 들어가보면?
결국 float의 Epsilon을 가져온다.
즉 float.Epsilon == Mathf.Epsilon임.(진짜 세세히 따지면 다른데 아무튼..)
나랑 같은 의문을 가진 사람이 이미 있었다 ㅋㅋ..
Mathf.Approximately 장단점
아무튼 Approximately는 내부적으로 하는 것도 많고
오차를 따로 사용자가 정할 수 없다는 게 단점이다.
그래도 쓰기도 편하고, 가독성도 좋고, 0의 근사치 비교에서 안전장치도 있고 해서 장점도 많다.
뺄셈을 통한 직접 구현(Epsilon)
직접 구현은 threshold값을 직접 정해줄 수 있음이 큰 장점이 된다.
또한 지금 버전은 간단히 구현한 것이라 안전 장치 등등이 없지만 필요에 의해 추가할 수 있고
그 뜻은 프로젝트에 필요한 것만 넣어 Approximately보다 좋은 성능을 낼 수 있다는 것.
(너무 당연한 소리인가..)
오차 허용 범위 조절
그리고 사실 float.Epsilon의 값도 오차 찾기에 너무 작은 값이라
보통의 프로젝트에서 이렇게 작은 값으로 할 필요도 없다.
오히려 threshold(오차 허용 범위)를 필요에 의해 크게 잡는 편이 많지..
오차 허용 범위를 더 좁히고 싶을 때
Approximately는 안 되지만 더 좁히는 것도 가능