변태 기질이 발동하여 sqrt를 직접 구현해보려고 했다. Show double root(double value) 바빌로니아 법으로 하면 대충 이렇다. for문을 많이 돌리면 많이 돌릴수록 근사된다. 같은 알고리즘을 sqrt와 바빌로니아 법으로 비교해보자 . 1. sqrt - 36ms 2. 직접 구현에서 for문을 100번 돌림 - 128ms 3. 직접 구현에서 for문을 20번 돌림 - 60ms 4. 직접 구현에서 for문을 11번 돌림 - 52 ms 5. 직접 구현에서 for문을 10번 돌림 - 틀렸습니다. sqrt는 어떻게 구현되어 있을까... 어딜가야 구현부를 볼 수 있는지 아시는분.. 알고리즘은 이러하다. 아마 비슷할듯.. 제곱근 구하는 함수를 처음 봤는데 구글에 검색하자마자 바로 눈에 보인건 구현 이였다. 그래서 나도 따라해본다(?)
SQRT 를 구현한 C 코드이다. 검색 해보니깐 제곱근을 구하는 알고리즘으로 바빌로니아 법 이라는 것을 찾을 수 있었다. x = (x + (A / x)) / 2 가 주된 결론인데. A는 제곱근을 구하고자 입력되는 값이고 x 는 0~ a 사이에 존재하는 임의의 값이다. 수식을 원하는 근사치가 나올때까지 반복 루프 돌리게 되는데, 루프를 많이 돌릴수록제곱근의 정확도가 높아진다. 이외에도 진짜 많은 자료가 있는데... 쓰면서 참고자료 링크 걸려다 보니깐 먼가 뻘짓한 기분도 들기도 하고... 링크 :: https://www.codeproject.com/Articles/69941/Best-Square-Root-Method-Algorithm-Function-Precisi 바빌로니아법(Babylonian method): 수학 공식으로 표현한 바빌로니아 법
C++언어로 구성한 바빌로니아 알고리즘 코딩 중 한 실수들:
고려해볼 만한 사항들
souvenir2020년/Dev Log [JS]바빌로니아 법을 이용해서 제곱근 구하기(Math.Sqrt 없이)풀빵이 2020. 5. 8. 15:40 0. 들어가며JS에서 제곱근을 구하는 것은 간단한 일이다. Mat.sqrt()을 활용하면 나오기 때문이다. 그러나 새로운 방식으로, 수학의 원리를 이용해 풀고싶은 생각이 들때도 있다. 4나 9의 제곱근을 구하는 것은 쉬운 일이지만 2의 제곱근만 해도 무한수이기에 쉽게 구하기 쉽지 않다. √2가 1과 2 사이의 숫자라는 것을 이용해 대략의 근삿값을 추측할 수 있을 뿐이었다. 과거 학창시절을 돌아보면 이런 두 수 사이의 범위를 활용하여 3√2와 2√3 중 어떤 숫자가 더 큰가를 비교하는 시절도 있던 것 같다. 옛날 사람들은 위와 같은 방법으로 근삿값을 구하는 공식을 만들었는데 이를 '바빌로니아 법'이라고 한다. 1. 바빌로니아 법이란※ 출처 : https://ko.wikipedia.org/wiki/%EB%B0%94%EB%B9%8C%EB%A1%9C%EB%8B%88%EC%95%84_%EB%B2%95 위 링크에 대한 예시가 이해가 되지 않아서 몇번 풀어보았다. 예시가 필요하신 분들은 아래 접은글 클릭 더보기 양의 실수 2에 대한 제곱근을 구해보고자 한다. 여기서 양의 실수를 a로 설정하였고, 초기값 x제로를 1로 설정해 보았을 때 아래와 같이 나온다. x의 값을 무한으로 실행해 볼 수록(lim x->∞) 근삿값은 더욱 가까워짐을 알 수 있다. 쉽게 이야기하면 이런 방식이다. 1) 양의 실수 6(변수 a)에 대해 √6의 근삿값을 구한다면 1-1) 뉴턴-랩슨 방법 활용양의 실수 a에 대한 제곱근 아래와 같이 표현할 수 있을 것이고, 이는 첫번째 식에서 N에 대한 해가 a의 제곱근과 같다는 것을 알 수 있다. 이런 점을 활용하여 이차방정식의 해의 근삿값, 혹은 (거의 같은 말이지만) 특정 함수의 역함수를 구하고자 활용되는 뉴턴-랩슨 방법을 활용하는 사람들도 있다. 문제는 이를 활용하기 위해서는 '점화식'이라는 개념이 필요한데 이것까지 이해하기는 어려워서 일단 C언어로나마 푸신 분의 알고리즘을 활용해보았지만 이분도 코드 오류가 많아서 제대로 돌아가지 않았다. ( 출처 : https://tyeolrik.github.io/data_structure/2017/01/21/7-newton-raphson-method-algorithm.html) 그 외에 다양한 글들을 검색해보았지만 대부분 C언어를 활용한 알고리즘 문제였기에 참고하기는 어려웠다. 그래서 다시 처음으로 돌아가 바빌로니아 법 자체를 다시 점검해보게 되었다. 2. 다시 바빌로니아 법을 활용하여 알고리즘 설정하기이를 활용하면서 전제를 정리해 보았다. 1) 임의의 양의 실수인 a는 두 제곱수 사이에 존재한다. 이를 수도코드로 정리해보자면 아래와 같다. (파라미터 : num) 1) 임의의 초기값(est)이 있다. 이를 코드로 적어보면 아래와 같다.
3. 피드백1) 초기값에 대해초기값은 임의로 설정해도 된다고 하는 문서가 많았는데 더 정확하게 하고 싶은 욕심(?) 때문인지, num이 특정 수 사이라는 것을 알 수 없기에 가변적으로 설정해줘야 한다는 강박 때문인지 초기값을 설정하는 함수에 너무 많은 시간을 투자하였다. 결론은 사실 초기값은 그냥 '1'로 설정해도 돌아간다는 점. 오히려 초기값 설정 때문에 코드가 정리되지 못한 것 같다는 생각이 든다. (이럴 때마다 느끼는 것이지만 JS가 생각보다 많이 느슨하게 적어도 인식하는 것 같다는... 물론 이 문제와는 관련 없는 특성이겠지만) 2) 알고리즘 설정에 대해처음 이 문제를 마주했을 때는 사실 '실전에서 이런 것을 부딪힐 일이 없을텐데...'라는 생각에 귀찮다는 생각도 들었고, 여러 수학 공식을 부딪히면서 포기하고 싶다는 생각도 들었지만 생각보다 간단한 접근, 혹은 초기의 생각으로 내가 직접 코드를 만들어보는 것에 많은 성취감을 느꼈다. 3) 도전하는 정신하지만 매일 할만한 것은 아니야 |