[Cuis-dev] Really fast Fibonacci function
Andres Valloud
ten at smallinteger.com
Sat Dec 7 18:42:31 PST 2019
Like this:
Integer>>karatsubaTimes: anInteger
^anInteger * self
LargeInteger>>karatsubaTimes: aLargeInteger
| splitThreshold
selfHigh selfLow aLargeIntegerHigh aLargeIntegerLow
highProduct lowProduct mixedProduct lowTerm |
self digitLength + aLargeInteger digitLength > 768 ifFalse: [^self *
aLargeInteger].
splitThreshold := self digitLength + aLargeInteger digitLength * 2.
selfHigh := self bitShift: splitThreshold negated.
selfLow := self - (selfHigh bitShift: splitThreshold).
aLargeIntegerHigh := aLargeInteger bitShift: splitThreshold negated.
aLargeIntegerLow := aLargeInteger - (aLargeIntegerHigh bitShift:
splitThreshold).
highProduct := selfHigh karatsubaTimes: aLargeIntegerHigh.
lowProduct := selfLow karatsubaTimes: aLargeIntegerLow.
mixedProduct := selfLow + selfHigh karatsubaTimes: aLargeIntegerLow +
aLargeIntegerHigh.
lowTerm := mixedProduct - (lowProduct + highProduct).
^((highProduct bitShift: splitThreshold)
+ lowTerm bitShift: splitThreshold)
+ lowProduct
Note the care taken with the specific operations as well as the order in
which they are performed.
By the way, it looks like I didn't remember well: the threshold was 384
bytes, not bits --- so about 3k bits for both, or 1.5k bits each.
Andres.
On 12/7/19 18:32, Andres Valloud via Cuis-dev wrote:
> (never mind the divisions, ouch!)
>
> On 12/7/19 18:29, Andres Valloud via Cuis-dev wrote:
>> Use base 2 rather than base 10, then those multiplications become bit
>> shifts.
>>
>> On 12/7/19 10:01, Agustín Sansone via Cuis-dev wrote:
>>> A small improvement, still not faster:
>>> f := 170 factorial.
>>> [1000 timesRepeat: [f squared]] timeToRun. 5
>>> [1000 timesRepeat: [f karatsuba: f]] timeToRun. 77
>>>
>>> El sáb., 7 dic. 2019 a las 13:02, Agustín Sansone
>>> (<agustinsansone7 at gmail.com <mailto:agustinsansone7 at gmail.com>>)
>>> escribió:
>>>
>>> Very quickly, Karatsuba's multiplication complexity of about
>>> n^1.6
>>> soundly beats the usual elementary n^2 multiplication algorithm,
>>> even if
>>> Karatsuba is implemented in the image while the n^2 algorithm is
>>> a VM
>>> primitive.
>>>
>>>
>>> Here is an implementation of Karatsuba's multiplication, but
>>> it doesn't seem to work faster for big numbers, maybe I did
>>> something wrong:
>>> f := 170 factorial.
>>> [1000 timesRepeat: [f squared]] timeToRun. 5
>>> [1000 timesRepeat: [f karatsuba: f]] timeToRun. 161
>>>
>>>
More information about the Cuis-dev
mailing list