Integer.st
changeset 13023 c7b914e6ed2b
parent 13022 43a439f72615
child 13367 fa81e6298411
equal deleted inserted replaced
13022:43a439f72615 13023:c7b914e6ed2b
  2571 
  2571 
  2572     "Modified: 18.7.1996 / 13:08:16 / cg"
  2572     "Modified: 18.7.1996 / 13:08:16 / cg"
  2573 !
  2573 !
  2574 
  2574 
  2575 binco:kIn
  2575 binco:kIn
       
  2576     "an alternative name for the binomial coefficient for squeak compatibility"
       
  2577 
  2576     ^ self binomialCoefficient:kIn
  2578     ^ self binomialCoefficient:kIn
       
  2579 
       
  2580     "Modified: / 17-08-2010 / 17:29:07 / cg"
  2577 !
  2581 !
  2578 
  2582 
  2579 binomialCoefficient:kIn
  2583 binomialCoefficient:kIn
  2580     "The binomial coefficient
  2584     "The binomial coefficient
  2581 
  2585 
  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...
  2895      Time millisecondsToRun:[400000 fib_helper]    6084
  2899      Time millisecondsToRun:[400000 fib_helper]    6084
  2896 
  2900 
  2897      1 to:100 do:[:i | self assert:(i fib_iterative = i fib_helper) ]
  2901      1 to:100 do:[:i | self assert:(i fib_iterative = i fib_helper) ]
  2898      1 to:100 do:[:i | self assert:(i fib_iterative = i fib) ]
  2902      1 to:100 do:[:i | self assert:(i fib_iterative = i fib) ]
  2899     "
  2903     "
       
  2904 
       
  2905     "Modified: / 17-08-2010 / 17:29:34 / cg"
  2900 !
  2906 !
  2901 
  2907 
  2902 gcd:anInteger
  2908 gcd:anInteger
  2903     "return the greatest common divisor of the receiver and anInteger.
  2909     "return the greatest common divisor of the receiver and anInteger.
  2904      Euclids & Knuths algorithm."
  2910      Euclids & Knuths algorithm."
  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. 
  4712 ! !
  4718 ! !
  4713 
  4719 
  4714 !Integer class methodsFor:'documentation'!
  4720 !Integer class methodsFor:'documentation'!
  4715 
  4721 
  4716 version
  4722 version
  4717     ^ '$Header: /cvs/stx/stx/libbasic/Integer.st,v 1.250 2010-08-17 15:28:16 cg Exp $'
  4723     ^ '$Header: /cvs/stx/stx/libbasic/Integer.st,v 1.251 2010-08-17 15:32:31 cg Exp $'
  4718 !
  4724 !
  4719 
  4725 
  4720 version_CVS
  4726 version_CVS
  4721     ^ '$Header: /cvs/stx/stx/libbasic/Integer.st,v 1.250 2010-08-17 15:28:16 cg Exp $'
  4727     ^ '$Header: /cvs/stx/stx/libbasic/Integer.st,v 1.251 2010-08-17 15:32:31 cg Exp $'
  4722 ! !
  4728 ! !
  4723 
  4729 
  4724 Integer initialize!
  4730 Integer initialize!