Levente Uzonyi uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ul.939.mcz ==================== Summary ==================== Name: Kernel-ul.939 Author: ul Time: 12 August 2015, 10:38:42.576 pm UUID: 6595484c-9c41-45fe-82f3-c689f7ddffa8 Ancestors: Kernel-eem.938 - Magnitude's spaceship operator uses quick returns. - Number >> #raisedTo: uses #negative and #isZero, which is faster for LargeIntegers than pure comparison with SmallIntegers. - faster #primesUpTo:do:, and #largePrimesUpTo:do: =============== Diff against Kernel-eem.938 =============== Item was changed: ----- Method: Integer class>>largePrimesUpTo:do: (in category 'prime numbers') ----- largePrimesUpTo: max do: aBlock "Evaluate aBlock with all primes up to maxValue. The Algorithm is adapted from http://www.rsok.com/~jrm/printprimes.html It encodes prime numbers much more compactly than #primesUpTo: 38.5 integer per byte (2310 numbers per 60 byte) allow for some fun large primes. (all primes up to SmallInteger maxVal can be computed within ~27MB of memory; + the regular #primesUpTo: would require one *GIGA*byte). - the regular #primesUpTo: would require 4 *GIGA*bytes). Note: The algorithm could be re-written to produce the first primes (which require the longest time to sieve) faster but only at the cost of clarity." + | n limit flags maskBitIndex bitIndex maskBit byteIndex index primesUpTo2310 indexLimit increments incrementIndex | - | limit flags maskBitIndex bitIndex maskBit byteIndex index primesUpTo2310 indexLimit | limit := max asInteger - 1. indexLimit := max asInteger sqrtFloor + 1. "Create the array of flags." flags := ByteArray new: (limit + 2309) // 2310 * 60 + 60. flags atAllPut: 16rFF. "set all to true" "Compute the primes up to 2310" primesUpTo2310 := self primesUpTo: 2310. "Create a mapping from 2310 integers to 480 bits (60 byte)" maskBitIndex := Array new: 2310. bitIndex := -1. "for pre-increment" maskBitIndex at: 1 put: (bitIndex := bitIndex + 1). maskBitIndex at: 2 put: (bitIndex := bitIndex + 1). + index := 1. + [ index <= 5 ] whileTrue: [ + aBlock value: (primesUpTo2310 at: index). + index := index + 1 ]. + + n := 2. + [ n <= 2309 ] whileTrue: [ - 1 to: 5 do:[:i| aBlock value: (primesUpTo2310 at: i)]. - - index := 6. - 2 to: 2309 do:[:n| [(primesUpTo2310 at: index) < n] whileTrue:[index := index + 1]. n = (primesUpTo2310 at: index) ifTrue:[ maskBitIndex at: n+1 put: (bitIndex := bitIndex + 1). ] ifFalse:[ "if modulo any of the prime factors of 2310, then could not be prime" (n \\ 2 = 0 or:[n \\ 3 = 0 or:[n \\ 5 = 0 or:[n \\ 7 = 0 or:[n \\ 11 = 0]]]]) ifTrue:[maskBitIndex at: n+1 put: 0] ifFalse:[maskBitIndex at: n+1 put: (bitIndex := bitIndex + 1)]. ]. + n := n + 1 ]. - ]. "Now the real work begins... Start with 13 since multiples of 2,3,5,7,11 are handled by the storage method; + increment by iterating through increments, which enables us to only check about 20.77% of all numbers." + n := 13. + increments := #[4 2 4 6 2 6 4 2 4 6 6 2 6 4 2 6 4 6 8 4 2 4 2 4 14 4 6 2 10 2 6 6 4 2 4 6 2 10 2 4 2 12 10 2 4 2 4 6 2 6 4 6 6 6 2 6 4 2 6 4 6 8 4 2 4 6 8 6 10 2 4 6 2 6 6 4 2 4 6 2 6 4 2 6 10 2 10 2 4 2 4 6 8 4 2 4 12 2 6 4 2 6 4 6 12 2 4 2 4 8 6 4 6 2 4 6 2 6 10 2 4 6 2 6 4 2 4 2 10 2 10 2 4 6 6 2 6 6 4 6 6 2 6 4 2 6 4 6 8 4 2 6 4 8 6 4 6 2 4 6 8 6 4 2 10 2 6 4 2 4 2 10 2 10 2 4 2 4 8 6 4 2 4 6 6 2 6 4 8 4 6 8 4 2 4 2 4 8 6 4 6 6 6 2 6 6 4 2 4 6 2 6 4 2 4 2 10 2 10 2 6 4 6 2 6 4 2 4 6 6 8 4 2 6 10 8 4 2 4 2 4 8 10 6 2 4 8 6 6 4 2 4 6 2 6 4 6 2 10 2 10 2 4 2 4 6 2 6 4 2 4 6 6 2 6 6 6 4 6 8 4 2 4 2 4 8 6 4 8 4 6 2 6 6 4 2 4 6 8 4 2 4 2 10 2 10 2 4 2 4 6 2 10 2 4 6 8 6 4 2 6 4 6 8 4 6 2 4 8 6 4 6 2 4 6 2 6 6 4 6 6 2 6 6 4 2 10 2 10 2 4 2 4 6 2 6 4 2 10 6 2 6 4 2 6 4 6 8 4 2 4 2 12 6 4 6 2 4 6 2 12 4 2 4 8 6 4 2 4 2 10 2 10 6 2 4 6 2 6 4 2 4 6 6 2 6 4 2 10 6 8 6 4 2 4 8 6 4 6 2 4 6 2 6 6 6 4 6 2 6 4 2 4 2 10 12 2 4 2 10 2 6 4 2 4 6 6 2 10 2 6 4 14 4 2 4 2 4 8 6 4 6 2 4 6 2 6 6 4 2 4 6 2 6 4 2 4 12 2 12]. + incrementIndex := 1. + [ n <= limit ] whileTrue: [ - increment by 2 for odd numbers only." - 13 to: limit by: 2 do:[:n| (maskBit := maskBitIndex at: (n \\ 2310 + 1)) = 0 ifFalse:["not a multiple of 2,3,5,7,11" byteIndex := n // 2310 * 60 + (maskBit-1 bitShift: -3) + 1. bitIndex := 1 bitShift: (maskBit bitAnd: 7). ((flags at: byteIndex) bitAnd: bitIndex) = 0 ifFalse:["not marked -- n is prime" aBlock value: n. "Start with n*n since any integer < n has already been sieved (e.g., any multiple of n with a number k < n has been cleared + when k was sieved); add 2 * n to avoid even numbers and - when k was sieved); add 2 * i to avoid even numbers and mark all multiples of this prime. Note: n < indexLimit below limits running into LargeInts -- nothing more." n < indexLimit ifTrue:[ index := n * n. [index <= limit] whileTrue:[ (maskBit := maskBitIndex at: (index \\ 2310 + 1)) = 0 ifFalse:[ byteIndex := (index // 2310 * 60) + (maskBit-1 bitShift: -3) + 1. maskBit := 255 - (1 bitShift: (maskBit bitAnd: 7)). flags at: byteIndex put: ((flags at: byteIndex) bitAnd: maskBit). ]. + index := index + n + n ]. - index := index + (2 * n)]. ]. ]. ]. + n := n + (increments at: incrementIndex). + incrementIndex := incrementIndex + 1. + incrementIndex > increments size ifTrue: [ incrementIndex := 1 ] ]! - ]. - ! Item was changed: ----- Method: Integer class>>primesUpTo:do: (in category 'prime numbers') ----- primesUpTo: max do: aBlock "Compute aBlock with all prime integers up to the given integer." "Integer primesUpTo: 100" + | index sieve increment limit limitSqrtFloor | - | index limit limitSqrtFloor sieve increment | limit := max asInteger. - limit <= 1 ifTrue: [ ^self ]. "Fall back into #largePrimesUpTo:do: if we'd require more than 100k of memory; + the alternative will only requre 2/77th of the amount we need here and is almost as fast." + limit <= 100000 ifFalse: [ ^self largePrimesUpTo: limit do: aBlock ]. - the alternative will only requre 1/154th of the amount we need here and is almost as fast." - limit > 25000 ifTrue:[ ^self largePrimesUpTo: limit do: aBlock ]. limit := limit - 1. "upTo:" + limit <= 1 ifTrue: [ ^self ]. + aBlock value: 2. + limit <= 2 ifTrue: [ ^self ]. + aBlock value: 3. + sieve := ByteArray new: limit withAll: 1. "1 = prime, 0 = not prime" + sieve at: 1 put: 0. + "Filter multiples of 2." + index := 4. + [ index <= limit ] whileTrue: [ + sieve at: index put: 0. + index := index + 2 ]. + "Filter multiples of 3." + index := 9. + [ index <= limit ] whileTrue: [ + sieve at: index put: 0. + index := index + 3 ]. + "Filter the rest of the primes." - sieve := Array new: limit withAll: true. - sieve at: 1 put: false. - index := 2. limitSqrtFloor := limit sqrtFloor. + index := 5. + increment := 2. - increment := 1. [ index <= limitSqrtFloor ] whileTrue: [ + (sieve at: index) = 1 ifTrue: [ + | originalIndex originalIncrement | - (sieve at: index) ifTrue: [ - | notPrimeIndex notPrimeIncrement | aBlock value: index. + originalIndex := index. + originalIncrement := increment. + increment := index + index. + index := index * index. + [ index <= limit ] whileTrue: [ + sieve at: index put: 0. + index := index + increment ]. + index := originalIndex. + increment := originalIncrement ]. - notPrimeIndex := index * index. - notPrimeIncrement := increment * index. - [ notPrimeIndex <= limit ] whileTrue: [ - sieve at: notPrimeIndex put: false. - notPrimeIndex := notPrimeIndex + notPrimeIncrement ] ]. index := index + increment. + increment := 6 - increment ]. + "No more new primes here." - increment := 2]. [ index <= limit ] whileTrue: [ + (sieve at: index) = 1 ifTrue: [ - (sieve at: index) ifTrue: [ aBlock value: index ]. index := index + increment. + increment := 6 - increment ]! - increment := 2]! Item was changed: ----- Method: Magnitude>><=> (in category 'sorting') ----- <=> anotherObject "Return a collation order of -1, 0, or 1, indicating whether I should be collated before the receiver, am equal, or after. See also: http://en.wikipedia.org/wiki/Spaceship_operator" + self = anotherObject ifTrue: [ ^0 ]. + self < anotherObject ifTrue: [ ^-1 ]. + ^1! - ^self = anotherObject - ifTrue: [0] - ifFalse: [self < anotherObject ifTrue: [-1] ifFalse: [1]]! Item was changed: ----- Method: Number>>raisedTo: (in category 'mathematical functions') ----- raisedTo: aNumber "Answer the receiver raised to aNumber." aNumber isInteger ifTrue: [ "Do the special case of integer power" ^ self raisedToInteger: aNumber]. aNumber isFraction ifTrue: [ "Special case for fraction power" ^ (self nthRoot: aNumber denominator) raisedToInteger: aNumber numerator ]. + self negative ifTrue: [ - self < 0 ifTrue: [ ^ ArithmeticError signal: 'Negative numbers can''t be raised to float powers.' ]. + aNumber isZero ifTrue: [^ self class one]. "Special case of exponent=0" - 0 = aNumber ifTrue: [^ self class one]. "Special case of exponent=0" 1 = aNumber ifTrue: [^ self]. "Special case of exponent=1" + self isZero ifTrue: [ "Special case of self = 0" + aNumber negative - 0 = self ifTrue: [ "Special case of self = 0" - aNumber < 0 ifTrue: [^ (ZeroDivide dividend: self) signal] ifFalse: [^ self]]. ^ (aNumber * self ln) exp "Otherwise use logarithms"! |
Free forum by Nabble | Edit this page |