|
| 1 | +--- |
| 2 | +layout: recipe |
| 3 | +title: Converting Radians and Degrees |
| 4 | +chapter: Math |
| 5 | +--- |
| 6 | + |
| 7 | +h2. Problem |
| 8 | + |
| 9 | +You would like to calculate a number N in the Fibonacci sequence but want |
| 10 | +to do it quickly. |
| 11 | + |
| 12 | +h2. Solution |
| 13 | + |
| 14 | +The following solution (which can still be improved on) was originally |
| 15 | +talked about on Robin Houston's blog. |
| 16 | + |
| 17 | +Here are a few links talking about the algorithm and ways to improve it: |
| 18 | +# <a href="http://bosker.wordpress.com/2011/04/29/the-worst-algorithm-in-the-world/">http://bosker.wordpress.com/2011/04/29/the-worst-algorithm-in-the-world/</a> |
| 19 | +# <a href="http://www.math.rutgers.edu/~erowland/fibonacci.html">http://www.math.rutgers.edu/~erowland/fibonacci.html</a> |
| 20 | +# <a href="http://jsfromhell.com/classes/bignumber">http://jsfromhell.com/classes/bignumber</a> |
| 21 | +# <a href="http://www.math.rutgers.edu/~erowland/fibonacci.html">http://www.math.rutgers.edu/~erowland/fibonacci.html</a> |
| 22 | +# <a href="http://bigintegers.blogspot.com/2010/11/square-division-power-square-root.html">http://bigintegers.blogspot.com/2010/11/square-division-power-square-root.html</a> |
| 23 | +# <a href="http://bugs.python.org/issue3451">http://bugs.python.org/issue3451</a> |
| 24 | + |
| 25 | +This code is in gist form here: |
| 26 | +<a href="https://gist.github.com/1032685">https://gist.github.com/1032685</a> |
| 27 | + |
| 28 | +{% highlight coffeescript %} |
| 29 | +### |
| 30 | +Author: Jason Giedymin <jasong _a_t_ apache -dot- org> |
| 31 | + http://www.jasongiedymin.com |
| 32 | + https://github.com/JasonGiedymin |
| 33 | + |
| 34 | +This CoffeeScript Javascript Fast Fibonacci code is |
| 35 | +based on the python code from Robin Houston's blog. |
| 36 | +See below links. |
| 37 | + |
| 38 | +A few things I want to introduce in time are implementions of |
| 39 | +Newtonian, Burnikel / Ziegler, and Binet's algorithms on top |
| 40 | +of a Big Number framework. |
| 41 | + |
| 42 | +Todo: |
| 43 | +- https://github.com/substack/node-bigint |
| 44 | +- BZ and Newton mods. |
| 45 | +- Timing |
| 46 | + |
| 47 | + |
| 48 | +### |
| 49 | + |
| 50 | +MAXIMUM_JS_FIB_N = 1476 |
| 51 | + |
| 52 | +fib_bits = (n) -> |
| 53 | + #Represent an integer as an array of binary digits. |
| 54 | + |
| 55 | + bits = [] |
| 56 | + while n > 0 |
| 57 | + [n, bit] = divmodBasic(n, 2) |
| 58 | + bits.push(bit) |
| 59 | + |
| 60 | + bits.reverse() |
| 61 | + return bits |
| 62 | + |
| 63 | +fibFast = (n) -> |
| 64 | + #Fast Fibonacci |
| 65 | + |
| 66 | + if n < 0 |
| 67 | + console.log "Choose an number >= 0" |
| 68 | + return |
| 69 | + |
| 70 | + [a, b, c] = [1, 0, 1] |
| 71 | + |
| 72 | + for bit in fib_bits(n) |
| 73 | + if bit |
| 74 | + [a, b] = [(a+c)*b, b*b + c*c] |
| 75 | + else |
| 76 | + [a, b] = [a*a + b*b, (a+c)*b] |
| 77 | + |
| 78 | + c = a + b |
| 79 | + return b |
| 80 | + |
| 81 | +divmodNewton = (x, y) -> |
| 82 | + throw new Error "Method not yet implemented yet." |
| 83 | + |
| 84 | +divmodBZ = () -> |
| 85 | + throw new Error "Method not yet implemented yet." |
| 86 | + |
| 87 | +divmodBasic = (x, y) -> |
| 88 | + ### |
| 89 | + Absolutely nothing special here. Maybe later versions will be Newtonian or |
| 90 | + Burnikel / Ziegler _if_ possible... |
| 91 | + ### |
| 92 | + |
| 93 | + return [(q = Math.floor(x/y)), (r = if x < y then x else x % y)] |
| 94 | + |
| 95 | +start = (new Date).getTime(); |
| 96 | +calc_value = fibFast(MAXIMUM_JS_FIB_N) |
| 97 | +diff = (new Date).getTime() - start; |
| 98 | +console.log("[#{calc_value}] took #{diff} ms.") |
| 99 | +{% endhighlight %} |
| 100 | + |
| 101 | +h2. Discussion |
| 102 | + |
| 103 | +Questions? |
0 commit comments