2805 ! |
2809 ! |
2806 |
2810 |
2807 fib_helper |
2811 fib_helper |
2808 "compute the fibionacci number for the receiver. |
2812 "compute the fibionacci number for the receiver. |
2809 |
2813 |
2810 Fib(n) = Fib(n-1) + Fib(n-2) |
2814 Fib(n) = Fib(n-1) + Fib(n-2) |
2811 |
2815 |
2812 Knuth: |
2816 Knuth: |
2813 Fib(n+m) = Fib(m) * Fib(n+1) + Fib(m-1) * Fib(n) |
2817 Fib(n+m) = Fib(m) * Fib(n+1) + Fib(m-1) * Fib(n) |
2814 |
2818 |
2815 This is about 3 times faster than fib_iterative. |
2819 This is about 3 times faster than fib_iterative. |
2816 " |
2820 " |
2817 |
2821 |
2818 |fibUsingDict dict| |
2822 |fibUsingDict dict| |
2819 |
2823 |
2820 dict := Dictionary new:100. |
2824 dict := Dictionary new:100. |
2821 |
2825 |
2822 fibUsingDict := [:x | |
2826 fibUsingDict := [:x | |
2823 |n fib fibN fibNp1 fibNm1 fibXm1 fibXm2 fibXp1| |
2827 |n fib fibN fibNp1 fibNm1 fibXm1 fibXm2 fibXp1| |
2824 |
2828 |
2825 x <= 30 ifTrue:[ |
2829 x <= 30 ifTrue:[ |
2826 "/ 0 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 |
2830 "/ 0 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 |
2827 fib := #(1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 |
2831 fib := #(1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 |
2828 ) at:x |
2832 ) at:x |
2829 ] ifFalse:[ |
2833 ] ifFalse:[ |
2830 fib := dict at:x ifAbsent:nil. |
2834 fib := dict at:x ifAbsent:nil. |
2831 fib isNil ifTrue:[ |
2835 fib isNil ifTrue:[ |
2832 fibXm1 := dict at:(x-1) ifAbsent:nil. |
2836 fibXm1 := dict at:(x-1) ifAbsent:nil. |
2833 fibXm1 notNil ifTrue:[ |
2837 fibXm1 notNil ifTrue:[ |
2834 fibXm2 := dict at:(x-2) ifAbsent:nil. |
2838 fibXm2 := dict at:(x-2) ifAbsent:nil. |
2835 fibXm2 notNil ifTrue:[ |
2839 fibXm2 notNil ifTrue:[ |
2836 fib := fibXm1 + fibXm2. |
2840 fib := fibXm1 + fibXm2. |
2837 ] ifFalse:[ |
2841 ] ifFalse:[ |
2838 fibXp1 := dict at:(x+1) ifAbsent:nil. |
2842 fibXp1 := dict at:(x+1) ifAbsent:nil. |
2839 fibXp1 notNil ifTrue:[ |
2843 fibXp1 notNil ifTrue:[ |
2840 fib := fibXp1 - fibXm1. |
2844 fib := fibXp1 - fibXm1. |
2841 ] |
2845 ] |
2842 ] |
2846 ] |
2843 ]. |
2847 ]. |
2844 |
2848 |
2845 fib isNil ifTrue:[ |
2849 fib isNil ifTrue:[ |
2846 n := x // 2. |
2850 n := x // 2. |
2847 x odd ifTrue:[ |
2851 x odd ifTrue:[ |
2848 "/ m is set to n+1; therefore: |
2852 "/ m is set to n+1; therefore: |
2849 "/ Fib(x) = Fib(n+n+1) ; x odd; setting n = (x-1)/2 |
2853 "/ Fib(x) = Fib(n+n+1) ; x odd; setting n = (x-1)/2 |
2850 "/ using Knuth: |
2854 "/ using Knuth: |
2851 "/ Fib(n+n+1) = Fib(n+1) * Fib(n+1) + Fib(n+1-1) * Fib(n) |
2855 "/ Fib(n+n+1) = Fib(n+1) * Fib(n+1) + Fib(n+1-1) * Fib(n) |
2852 "/ = (Fib(n+1) ^ 2) + (Fib(n) ^ 2) |
2856 "/ = (Fib(n+1) ^ 2) + (Fib(n) ^ 2) |
2853 fibN := fibUsingDict value:n. |
2857 fibN := fibUsingDict value:n. |
2854 fibNp1 := fibUsingDict value:(n+1). |
2858 fibNp1 := fibUsingDict value:(n+1). |
2855 fib := fibN squared + fibNp1 squared |
2859 fib := fibN squared + fibNp1 squared |
2856 ] ifFalse:[ |
2860 ] ifFalse:[ |
2857 "/ as |
2861 "/ as |
2858 "/ Fib(n+1) = Fib(n) + Fib(n-1) |
2862 "/ Fib(n+1) = Fib(n) + Fib(n-1) |
2859 "/ therefore: |
2863 "/ therefore: |
2860 "/ Fib(n) = Fib(n+1) - Fib(n-1) |
2864 "/ Fib(n) = Fib(n+1) - Fib(n-1) |
2861 "/ and, since n is even, n+1 and n-1 are odd, and can be computed as above. |
2865 "/ and, since n is even, n+1 and n-1 are odd, and can be computed as above. |
2862 "/ This gives us: |
2866 "/ This gives us: |
2863 "/ Fib(x) = Fib(x+1) - Fib(x-1) ; x even; setting n = x/2 |
2867 "/ Fib(x) = Fib(x+1) - Fib(x-1) ; x even; setting n = x/2 |
2864 "/ = Fib(n+n+1) - Fib(n+n-1) |
2868 "/ = Fib(n+n+1) - Fib(n+n-1) |
2865 "/ = Fib(n+n+1) - Fib((n-1)+(n-1)+1) |
2869 "/ = Fib(n+n+1) - Fib((n-1)+(n-1)+1) |
2866 "/ = ((Fib(n+1)^2) + (Fib(n)^2)) - ((Fib((n-1)+1)^2) + (Fib((n-1))^2)) |
2870 "/ = ((Fib(n+1)^2) + (Fib(n)^2)) - ((Fib((n-1)+1)^2) + (Fib((n-1))^2)) |
2867 "/ = (Fib(n+1)^2) + (Fib(n)^2) - (Fib(n)^2) - (Fib((n-1))^2) |
2871 "/ = (Fib(n+1)^2) + (Fib(n)^2) - (Fib(n)^2) - (Fib((n-1))^2) |
2868 "/ = (Fib(n+1)^2) - (Fib((n-1))^2) |
2872 "/ = (Fib(n+1)^2) - (Fib((n-1))^2) |
2869 fibNm1 := fibUsingDict value:(n-1). |
2873 fibNm1 := fibUsingDict value:(n-1). |
2870 fibNp1 := fibUsingDict value:(n+1). |
2874 fibNp1 := fibUsingDict value:(n+1). |
2871 fib := fibNp1 squared - fibNm1 squared |
2875 fib := fibNp1 squared - fibNm1 squared |
2872 ]. |
2876 ]. |
2873 ]. |
2877 ]. |
2874 dict at:x put:fib. |
2878 dict at:x put:fib. |
2875 ] |
2879 ] |
2876 ]. |
2880 ]. |
2877 fib |
2881 fib |
2878 ]. |
2882 ]. |
2879 |
2883 |
2880 ^ fibUsingDict value:self |
2884 ^ fibUsingDict value:self |
2881 |
2885 |
2882 "the running time is mostly dictated by the LargeInteger multiplication performance... |
2886 "the running time is mostly dictated by the LargeInteger multiplication performance... |
2942 b := self highBit. |
2948 b := self highBit. |
2943 rem := 1 bitShift:b. |
2949 rem := 1 bitShift:b. |
2944 result := LargeInteger basicNew numberOfDigits:(b // 8)+1. |
2950 result := LargeInteger basicNew numberOfDigits:(b // 8)+1. |
2945 b := b+1. |
2951 b := b+1. |
2946 [b > 0] whileTrue:[ |
2952 [b > 0] whileTrue:[ |
2947 rem >= self ifTrue:[ |
2953 rem >= self ifTrue:[ |
2948 rem := rem -= self. |
2954 rem := rem -= self. |
2949 result digitBytes bitSetAt:b. |
2955 result digitBytes bitSetAt:b. |
2950 ]. |
2956 ]. |
2951 rem := rem mul2. |
2957 rem := rem mul2. |
2952 b := b - 1. |
2958 b := b - 1. |
2953 ]. |
2959 ]. |
2954 ^ result compressed. |
2960 ^ result compressed. |
2955 |
|
2956 |
2961 |
2957 " |
2962 " |
2958 333 integerReciprocal (2 raisedTo:18) // 333 |
2963 333 integerReciprocal (2 raisedTo:18) // 333 |
2959 393 integerReciprocal |
2964 393 integerReciprocal |
2960 8 integerReciprocal |
2965 8 integerReciprocal |
2961 15 integerReciprocal |
2966 15 integerReciprocal |
2962 15112233445566 integerReciprocal |
2967 15112233445566 integerReciprocal |
2963 10239552311579 integerReciprocal |
2968 10239552311579 integerReciprocal |
2964 " |
2969 " |
2965 |
2970 |
2966 "Modified: / 3.5.1999 / 14:27:18 / stefan" |
2971 "Modified: / 03-05-1999 / 14:27:18 / stefan" |
|
2972 "Modified: / 17-08-2010 / 17:30:22 / cg" |
2967 ! |
2973 ! |
2968 |
2974 |
2969 integerSqrt |
2975 integerSqrt |
2970 "newton's method to get the largest integer which is less or equal to the |
2976 "newton's method to get the largest integer which is less or equal to the |
2971 receiver's square root. |
2977 receiver's square root. |