1
+ #include <math.h>
1
2
#include <stdio.h>
2
3
#include <stdlib.h>
3
4
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
+
4
53
static int mySqrt (int x )
5
54
{
6
55
if (x == 0 ) {
@@ -9,18 +58,21 @@ static int mySqrt(int x)
9
58
10
59
unsigned int left = 1 ;
11
60
unsigned int right = (unsigned int ) x ;
61
+ unsigned int mid = left + (right - left ) / 2 ;
12
62
for (; ;) {
13
- unsigned int mid = left + (right - left ) / 2 ;
14
63
if (mid > x /mid ) {
15
64
right = mid ;
16
65
} else {
17
66
if (mid + 1 > x /(mid + 1 )) {
18
- return mid ;
67
+ break ;
19
68
} else {
20
69
left = mid ;
21
70
}
22
71
}
72
+ mid = left + (right - left ) / 2 ;
23
73
}
74
+
75
+ return mid ;
24
76
}
25
77
26
78
int main (int argc , char * * argv )
@@ -30,6 +82,7 @@ int main(int argc, char **argv)
30
82
exit (-1 );
31
83
}
32
84
85
+ //printf("%f\n", mySqrt(1.5));//atoi(argv[1])));
33
86
printf ("%d\n" , mySqrt (atoi (argv [1 ])));
34
87
return 0 ;
35
88
}
0 commit comments