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
µÈ´Ù. µû¶ó¼ Æò¹æ±ÙÀÇ °è»ê¿¡ ´ëÇØ, º»¾Ë°í¸®ÁòÀÇ ¹æ¹ý¿¡¼´Â ´ºÅϹýµî ´Ù¸¥ ¹æ¹ýº¸´Ù È¿À²ÀÌ ÁÁ°í, ¸îÂ÷·ÊÀÇ °è»êÀ¸·Î ÇÊ¿ä·Î ÇÏ´Â Á¤¹ÐµµÀÇ °ÍÀ» ¾òÀ» ¼ö ÀÖ´Ù.