On Wednesday, February 17, 2021 at 9:38:09 PM UTC+1 John K wrote:

> Hi Sorawee,
>
> On Feb 17, 2021, at 3:20 PM, Sorawee Porncharoenwase <[email protected]> 
> wrote:
>
>  

> Why did you try to implement your own version in the first place?
>
> Just as a learning exercise…
>
> I didn’t see any obvious performance difference, but I guess if I compare 
> the two implementations, I would say:
>
> 1. modular-expt uses infix operators (which looked strange to me in Racket 
> context FWIW but is clearly just my personal taste).
>

I think, Neil liked (a . < . b) over (< a b). For consistency, I prefer (< 
a b).
 

> 2. modular-expt uses the ‘loop’ syntax (taking an extra dependency that 
> seems not needed for a bitwise shift to get equivalent performance).
>

I was curious, so I looked up the code: 

  (: modular-expt* (Positive-Integer Integer Integer -> Natural))
  ;; Exponentiate by repeated modular multiplication and squaring
  (define (modular-expt* n a b)
    (cond 
          [(b . < . 0)  (raise-argument-error 'modular-expt "Natural" 1 a b 
n)]
          [(b . = . 0)  (if (n . = . 1) 0 1)]
          [else
           (let ([a (modulo a n)])
             (let loop ([b b])
               (cond [(b . = . 1)  a]
                     [(even? b)  (define c (loop (quotient b 2)))
                                         (modulo (* c c) n)]
                     [else           (modulo (* a (loop (sub1 b))) n)])))]))

I expect that (quotient b 2) is implemented as a bitshift. That would 
explain why you don't see any difference.

The loop syntax is called "named let", and is just a convenience.

/Jens Axel


-- 
You received this message because you are subscribed to the Google Groups 
"Racket Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-dev/8ebb6ec0-5479-4b07-b862-07989ebb4ac9n%40googlegroups.com.

Reply via email to