Newton의 방법의 문제점 중 하나는 각 반복마다 나누기 연산이 필요하다는 것입니다. 이는 가장 느린 기본 정수 연산입니다.
그러나 역 제곱근에 대한 뉴턴의 방법은 그렇지 않습니다. 만약엑스 찾고자하는 번호입니다 1엑스√반복 :
아르 자형나는 + 1=12아르 자형나는(3−xr2i)
이것은 종종 다음과 같이 표현됩니다 :
wi=r2i
di=1−wix
ri+1=ri+ridi2
세 번의 곱셈 연산입니다. 2 개로 나누는 것은 오른쪽 이동으로 구현할 수 있습니다.
이제 문제는 r정수가 아닙니다. 그러나 부동 소수점을 수동으로 구현하고 적절한 경우 보상하기 위해 많은 시프트 연산을 수행하여이를 조작 할 수 있습니다.
먼저 크기를 조정하겠습니다 x:
x′=2−2ex
우리가 원하는 곳 x′ 보다 크지 만 가까이 있어야합니다 1. 위의 알고리즘을 실행하면x′ 대신에 x, 우리는 찾는다 r=1x√′. 그때,x−−√=2erx′.
이제 나누자 r 가수와 지수로 :
ri=2−eir′i
어디 r′i정수입니다. 직관적으로ei 답의 정확성을 나타냅니다.
우리는 뉴턴의 방법이 정확한 유효 자릿수의 두 배를 가짐을 알고 있습니다. 그래서 우리는 선택할 수 있습니다 :
ei+1=2ei
약간의 조작만으로 우리는 다음을 발견합니다.
ei+1=2ei
wi=r′i2
x′i=x22e−ei+1
di=2ei+1−w′ix′i2ei+1
r′i+1=2eir′i−r′idi2ei+1
반복 할 때마다 :
x−−√≈r′ix2e+ei
예를 들어, 제곱근을 계산해 봅시다 x=263. 우리는 그 답이2312–√. 상호 제곱근은12√2−31그래서 우리는 설정합니다 e=31 (이것은 문제의 규모입니다) 첫 번째 추측을 위해 우리는 선택할 것입니다 r′0=3 과 e0=2. (즉, 우리는34 초기 추정치 12√.)
그때:
e1=4,r′1=11
e2=8,r′2=180
e3=16,r′3=46338
e4=32,r′4=3037000481
우리는 반복을 멈추는 시점을 비교하여 해결할 수 있습니다. ei 에 e; 내가 정확하게 계산했다면ei>2e충분해야합니다. 우리는 여기서 멈추고 다음을 찾습니다.
263−−−√≈3037000481×263231+32=3037000481
올바른 정수 제곱근은 3037000499우리는 아주 가깝습니다. 또 다른 반복을 수행하거나 최적화되지 않은 최종 반복을 수행 할 수 있습니다.ei. 세부 사항은 연습으로 남습니다.
To analyse the complexity of this method, note that multiplying two b-bit integers takes O(blogb) operations. However, we have arranged things so that r′i<2ei. So the multiplication to calculate wi multiplies two ei-bit numbers to produce a ei+1-bit number, and the other two multiplications multiply two ei+1-bit numbers to produce a 2ei+1-bit number.
In each case, the number of operations per iteration is O(eilogei), and there are O(loge) iterations required. The final multiplication is on the order of O(2elog2e) operations. So the overall complexity is O(elog2e) operations, which is sub-quadratic in the number of bits in x. That ticks all the boxes.
However, this analysis hides an important principle which everyone working with large integers should keep in mind: because multiplication is superlinear in the number of bits, any multiplication operations should only be performed on integers which have the roughly the magnitude of the current precision (and, I might add, you should try to multiply numbers together which have a similar order of magnitude). Using integers larger than that is a waste of effort. Constant factors matter, and for large integers, they matter a lot.
As a final observation, two of the multiplications are of the form ab2c. Clearly it's wasteful to compute the all the bits of ab only to throw c of them away with a right-shift. Implementing a smart multiplication method which takes this into account is also left as an exercise.