I was practicing Scheme in Guile 1.8.8
interpreter on OS X. I noticed something interesting.
Here's expt
function which is basically does exponentiation expt(b,n) = b^n
:
(define (square x) (* x x)) (define (even? x) (= (remainder x 2) 0)) (define (expt b n) (cond ((= n 0) 1) ((even? n) (square (expt b (/ n 2)))) (else (* b (expt b (- n 1)))) ))
If I try it with some inputs
> (expt 2 10) 1024 > (expt 2 63) 9223372036854775808
Here comes the strange part:
> (expt 2 64) 0
More strangely, until n=488
it stays at 0
:
> (expt 2 487) 0 > (expt 2 488) 79916762888089401123..... > (expt 2 1000) 1071508607186267320948425049060.... > (expt 2 10000) 0
When I try this code with repl.it online interpreter, it works as expected. So what the hell is wrong with Guile?
(Note: On some dialects, remainder
function is called as mod
.)
I recently fixed this bug in Guile 2.0. The bug came into existence when C compilers started optimizing out overflow checks, on the theory that if a signed integer overflow occurs then the behavior is unspecified and thus the compiler can do whatever it likes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With