-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSqrtX_68.java
More file actions
73 lines (69 loc) · 2.19 KB
/
Copy pathSqrtX_68.java
File metadata and controls
73 lines (69 loc) · 2.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package com.leetcode.binarysearch;
/**
* Created by charles on 4/13/17.
* Implement int sqrt(int x).
Compute and return the square root of x.
*/
public class SqrtX_68 {
/** naive solution, binary search, each time only pick mid
* then compare mid with x/mid
*/
public int mySqrt(int x) {
if (x == 0) {
return 0;
}
int left = 0, right = x;
int mid = 0;
while (true) {
mid = left + (right - left) / 2;
if (mid > x / mid) { // to avoid overflow
right = mid - 1;
} else {
// expect result is integer
// thus diff is 1 at most.
if (mid + 1 > x / (mid + 1)) {
return mid;
}
left = mid + 1;
}
}
}
/** newton solution, based on formula
* r = 1/2 * (r + a/r)
* to calculate r = a ^ 1/2, square root of a
* */
public int mySqrtII(int a) {
long r = a;
while (r * r > a) {
r = (r + a/r) / 2;
}
return (int)r;
}
/**
* best way is Carmack's method.
* to find inverse square root of float number
* http://en.wikipedia.org/wiki/Fast_inverse_square_root
* Carmack's method is fast because:
The initial guess is super accurate.
Does not use division.
Does not use loops.
Carmack's method is no longer useful nowadays and this is just for fun.
http://www.procedurego.com/article/180938.html
*/
public float inverseSqrt(float x) {
float half = 0.5f * x;
int i = Float.floatToIntBits(x); // get bits for floating value
i = 0x5f3759df - (i >> 1); // give initial guess for 1/sqrt()
x = Float.intBitsToFloat(i); // convert bits back to float
x *= (1.5f - half * x * x); // newton step, repeating increases accuracy
return x;
}
public double inverseSqrt(double x) {
double xhalf = 0.5d * x;
long i = Double.doubleToLongBits(x);
i = 0x5fe6ec85e7de30daL - (i >> 1); // this magic number for double
x = Double.longBitsToDouble(i);
x *= (1.5d - xhalf * x * x);
return x;
}
}