squareRoot 1 ¿¡¼ 99 ÀÇ »çÀÌÀÇ Æò¹æ±ÙÀÇ °ªÀ» ´ÙÀÚ¸®¼ö·Î »êÃâÇÑ´Ù.
int squareRoot(int *data, int keta, int n);
data (Ãâ·Â) Æò¹æ±ÙÀÇ °ªÀÌ 10Áø 4ÀÚ¸®¼ö¾¿ µé¾î°£ Á¤¼öÀÇ ¹è¿ keta (ÀÔ·Â) ¼Ò¼öÁ¡ ÀÌÇÏÀÇ ÀÚ¸®¼öÀÇ ÁöÁ¤ n (ÀÔ·Â) °è»êÇÏ·Á°í ÇÏ´Â Æò¹æ±ÙÀÇ 2½ÂÀÇ °ª
Á¤»óÀûÀ¸·Î °è»êÇÒ ¼ö ÀÖ¾úÀ» ¶§¿¡, °è»ê °á°ú°¡ µÇ´Â data ÀÇ ±æÀÌ. ¿¡·¯ ¶§ 0.
int squareRoot(int *data, int keta, int n)
{
int *pbuf, *qbuf, *tbuf;
int *pp, *qq, *tt;
int pketa, qketa;
int i;
int ret;
static long p0[101] = { /* p0*p0 = 4+n*q0*q0 */
0,-1, 6726, 2702, -2, 5778, 9602, 4048, 6726, -3, 1442,
7940, 2702, 1298, 898, 3842, -4, 4354, 1154, 340, 5778,
2525, 394, 2302, 9602, -5, 102, 2702, 4048, 727, 482,
3040, 6726, 2114, 4898, 1692, -6, 146, 5474, 2498, 1442,
4098, 674, 6964, 7940, 2207,48670L, 9214, 2702, -7, 198,
9998, 1298, 2599, 970, 178, 898, 302,39206L, 1060,3842,
1523, 126, 4048, -8, 258, 130,97684L, 4354, 623, 502,
6960, 1154,4562498L, 7398,2702, 340, 6239, 106, 160, 5778,
-9, 326, 164, 110, 6887, 20810, 3134, 394,1000002L, 1442,
3148, 2302, 839,4286590L, 6082,9602,125619266L, 198,7940,-10 };
static long q0[101] = {
0,-1, 4756, 1560, -2, 2584, 3920, 1530, 2378, -3, 456,
2394, 780, 360, 240, 992, -4, 1056, 272, 78, 1292,
551, 84, 480, 1960, -5, 20, 520, 765, 135, 88,
546, 1189, 368, 840, 286, -6, 24, 888, 400, 228,
640, 104, 1062, 1197, 329, 7176, 1344, 390, -7, 28,
1400, 180, 357, 132, 24, 120, 40, 5148, 138, 496,
195, 16, 510, -8, 32, 16,11934, 528, 75, 60,
826, 136,534000L, 860, 312, 39, 711, 12, 18, 646,
-9, 36, 18, 12, 747, 2244, 336, 42,106000L, 152,
330, 240, 87,442128L, 624, 980,12754704L, 20, 798, -10 };
if (n < 1 || n > 100 || keta < 1) return 0;
if (p0[n] < 0) {
*data = -p0[n];
return 1;
}
if (p0[n]*p0[n] ! = 4 + q0[n]*q0[n]*n)
return 0; /* Oh, my God ! */
ret = 0;
pbuf = qbuf = tbuf = NULL;
pbuf = (int *) calloc(2*keta+3, sizeof(int));
qbuf = (int *) calloc(keta+3, sizeof(int));
tbuf = (int *) calloc(keta+3, sizeof(int));
if (pbuf ! = NULL && qbuf ! = NULL && tbuf ! = NULL) {
if (p0[n] > 10000)
*pbuf = p0[n]%10000, *(pbuf+1) = p0[n]/10000, pketa = 2;
else *pbuf = p0[n], pketa = 1;
if (q0[n] > 10000)
*qbuf = q0[n]%10000, *(qbuf+1) = q0[n]/10000, qketa = 2;
else *qbuf = q0[n], qketa = 1;
while (qketa*4 < keta) {
/* q = p * q */
qketa = mulf(tbuf, pbuf, pketa, qbuf, qketa);
for (tt = tbuf, qq = qbuf, i = qketa; i > 0; i--) *qq++ = *tt++;
/* p = p * p - 2 */
pketa = mulf(tbuf, pbuf, pketa, pbuf, pketa);
for (tt = tbuf, pp = pbuf, i = pketa; i > 0; i--) *pp++ = *tt++;
*pbuf -= 2;
}
ret = divf(data, pbuf, pketa, qbuf, qketa, tbuf);
}
if (tbuf ! = NULL) free(tbuf);
if (pbuf ! = NULL) free(qbuf);
if (qbuf ! = NULL) free(pbuf);
return ret;
}
/* mm <-- aa * bb */
static int mulf(int *mm, int *aa, int la, int *bb, int lb)
{
int i, j;
int *a, *b, *m;
int lm, ca;
long x;
for (m = mm, i = la + lb; i > 0; i--) *m++ = 0;
for (b = bb, j = 0; j < lb; j++, b++) {
for (ca = 0, a = aa, i = 0; i < la; i++) {
x = *a++;
x = x * *b + *(mm + i + j) + ca;
*(mm + i + j) = x % 10000;
ca = x / 10000;
}
*(mm + i + j) = ca;
}
return la + lb - (ca == 0);
}
/* qq <-- aa / bb */
static int divf(int *qq, int *aa, int la, int *bb, int lb, int *tt)
{
int i;
int *a, *b, *q, *t, *s;
int ca, k, Q, lt, lq, m;
long x;
for (a = aa + la + lb, s = aa + la, i = la; i > 0; i--) *--a = *--s;
for (i = lb; i > 0; i--) *--a = 0;
la += lb;
if ((k = 4999 / *(bb + lb - 1) + 1) > 1) {
for (ca = 0, a = aa, t = tt, i = 0; i < la; i++) {
x = (long) k * *a++ + ca;
*t++ = x % 10000, ca = x / 10000;
}
*t = ca;
la = i + (ca > 0);
for (t = tt, a = aa, i = la; i > 0; i--) *a++ = *t++;
for (ca = 0, b = bb, t = tt, i = 0; i < lb; i++) {
x = (long) k * *b++ + ca;
*t++ = x % 10000, ca = x / 10000;
}
*t = ca;
lb = i + (ca > 0);
for (t = tt, b = bb, i = lb; i > 0; i--) *b++ = *t++;
}
lq = la - lb + 1;
for (q = qq, i = lq; i > 0; i--) *q++ = 0;
while ((m = la) >= lb) {
if (*(aa + la - 1) >= *(bb + lb - 1)) {
for (a = aa + la - 1, b = bb + lb - 1; b ! = bb; a--, b--)
if (*a ! = *b) break;
if (b == bb) {
*(qq + la - lb) = 1;
la -= lb;
continue;
} else if (*a > *b) {
for (s = b, ca = 0, a = aa + la - lb, b = bb; b <= s; a++) {
*a -= *b++ + ca;
ca = 0;
if (*a < 0) *a += 10000, ca = 1;
}
while (*--a == 0) ;
*(qq + la - lb) = 1;
la = a - aa + 1;
continue;
}
Q = 9999;
} else Q = (10000L * *(aa+la-1) + *(aa+la-2)) / *(bb+lb-1);
if (la == lb) break;
for ( ; ; ) {
if (Q == 1) {
*(bb + lb) = 0;
for (ca=0, a=aa+(la-lb-1), b=bb, i=lb; i >= 0; i--, a++) {
*a -= *b++ + ca;
ca = 0;
if (*a < 0) *a += 10000, ca = 1;
}
while (*--a == 0) ;
la = a - aa + 1;
break;
}
for (ca = 0, t = tt, b = bb, i = 0; i < lb; i++) {
x = (long) Q * *b++ + ca;
*t++ = x % 10000, ca = x / 10000;
}
*t = ca;
lt = i + 1;
for (a = aa + la - 1, t = tt + lt - 1; t ! = tt; a--, t--)
if (*a ! = *t) break;
if (t == tt) {
la -= lt;
break;
} else if (*a > *t) {
for (s=t, ca=0, a = aa+(la-lt), t = tt; t <= s; a++) {
*a -= *t++ + ca;
ca = 0;
if (*a < 0) *a += 10000, ca = 1;
}
while (*--a == 0) ;
la = a - aa + 1;
break;
} else Q--;
}
*(qq + m - lb - 1) = Q;
}
if (*(qq + lq - 1) == 0) lq--;
return lq;
}
¡¡¡¡¡¡¡¡pi+1 = pi2 - 2
¡¡¡¡¡¡¡¡qi+1 = pi qi
(À»)¸¦ °è»êÇØ, ¸¶Áö¸·À¸·Î, pi+1 / qi+1 ·Î Æò¹æ±ÙÀ» ¿ä±¸ÇÑ´Ù.
µ¡ºÙ¿© ÃʱâÄ¡ p0, q0 Àº Æç ¹æÁ¤½Ä p02 - M q02 = 4 ¸¦ ä¿î´Ù Á¤¼öÇØÀÌ´Ù. ´Ù¸¸, M ´Â °è»êÇÏ·Á°í ÇÏ´Â Æò¹æ±ÙÀÇ 2½ÂÀÇ °ª.
¼öÇÐÀû ±Í³³¹ýÀ¸·Î Áõ¸íÇÒ ¼ö ÀÖÁö¸¸, À§ÀÇ Á¡È½Ä¿¡¼ ¾òÀ» ¼ö ÀÖ´ø pi+1, qi+1 ¿¡ ÀÇÇØ,
¡¡¡¡¡¡¡¡pi+1 / qi+1 = (M + 4 / (pi qi)2)1 / 2
µÈ´Ù. µû¶ó¼ Æò¹æ±ÙÀÇ °è»ê¿¡ ´ëÇØ, º»¾Ë°í¸®ÁòÀÇ ¹æ¹ý¿¡¼´Â ´ºÅϹýµî ´Ù¸¥ ¹æ¹ýº¸´Ù È¿À²ÀÌ ÁÁ°í, ¸îÂ÷·ÊÀÇ °è»êÀ¸·Î ÇÊ¿ä·Î ÇÏ´Â Á¤¹ÐµµÀÇ °ÍÀ» ¾òÀ» ¼ö ÀÖ´Ù.