1+ #include <math.h>
12#include <stdio.h>
23#include <stdlib.h>
34
5+ #if 0
6+ static double mySqrt (double x )
7+ {
8+ double lo = 0 ;
9+ double hi = x ;
10+ double diff = 1e-8 ;
11+ double mid = (lo + hi ) / 2 ;
12+ while (fabs (mid * mid - x ) > diff ) {
13+ if (mid < x / mid ) {
14+ lo = mid ;
15+ } else if (mid > x / mid ) {
16+ hi = mid ;
17+ } else {
18+ break ;
19+ }
20+ mid = (lo + hi ) / 2 ;
21+ }
22+
23+ return mid ;
24+ }
25+
26+ static double mySqrt (double n )
27+ {
28+ /* Solute the zero point of f(x) = 0 => x ^ 2 - n = 0 */
29+ /* f(x) = (x - x0)f'(x0) - f(x0) = 0 First order of Tylor series */
30+ double x = 1.0 ;
31+ while (fabs (x * x - n ) > 1e-8 ) {
32+ x = x - (x * x - n ) / (2 * x );
33+ }
34+ return x ;
35+ }
36+
37+ static double mySqrt (double n )
38+ {
39+ /* Gradient descent
40+ * MSE Loss = (x * x - n) ^ 2
41+ * G = 4 * x ^ 3 - 4 * n * x
42+ * x = x - a * G
43+ */
44+ double a = 1e-4 ;
45+ double x = 1.0 ;
46+ while (fabs (x * x - n ) > 1e-8 ) {
47+ x = x - a * 4 * x * (x * x - n );
48+ }
49+ return x ;
50+ }
51+ #endif
52+
453static int mySqrt (int x )
554{
655 if (x == 0 ) {
@@ -9,18 +58,21 @@ static int mySqrt(int x)
958
1059 unsigned int left = 1 ;
1160 unsigned int right = (unsigned int ) x ;
61+ unsigned int mid = left + (right - left ) / 2 ;
1262 for (; ;) {
13- unsigned int mid = left + (right - left ) / 2 ;
1463 if (mid > x /mid ) {
1564 right = mid ;
1665 } else {
1766 if (mid + 1 > x /(mid + 1 )) {
18- return mid ;
67+ break ;
1968 } else {
2069 left = mid ;
2170 }
2271 }
72+ mid = left + (right - left ) / 2 ;
2373 }
74+
75+ return mid ;
2476}
2577
2678int main (int argc , char * * argv )
@@ -30,6 +82,7 @@ int main(int argc, char **argv)
3082 exit (-1 );
3183 }
3284
85+ //printf("%f\n", mySqrt(1.5));//atoi(argv[1])));
3386 printf ("%d\n" , mySqrt (atoi (argv [1 ])));
3487 return 0 ;
3588}
0 commit comments