On 03.05.2014 21:01, Stas Boukarev wrote:
> I get a different result:
> (SB-GMP:MPZ-POW -15546163094340153687 11)
>
[...]
>
> Which
>
> is equal to (ldb (byte 704 0) (expt -15546163094340153687 11)), so,
> there's a problem with sign extension.
>
Yes, replace with the follow macro; I haven't committed yet, because of
the strange results when requiring the test-suite:
(defmacro with-gmp-mpz-results (resultvars &body body)
(loop for gres in resultvars
for res = (gensym "RESULT")
for size = (gensym "SIZE")
collect size into sizes
collect `(,gres (struct gmpint)) into declares
collect `(__gmpz_init (addr ,gres)) into inits
collect `(,size (1+ (abs (slot ,gres 'mp_size))))
into resinits
collect `(when (> ,size (1- sb-bignum::maximum-bignum-length)) (error "Size of result exceeds maxim bignum
length")) into checks
collect `(,res (%allocate-bignum (1+ ,size)))
into resallocs
collect `(setf ,res (if (minusp (slot ,gres 'mp_size)) ; check
for negative result ;(gmp-z-to-bignum-neg (slot ,gres
'mp_d) ,res ,size) (negate-bignum (gmp-z-to-bignum (slot
,gres 'mp_d) ,res ,size) nil) (gmp-z-to-bignum (slot ,gres 'mp_d)
,res ,size)))
into copylimbs
collect `(__gmpz_clear (addr ,gres)) into clears
collect res into results
finally (return `(with-alien ,declares ,@inits ,@body (let ,resinits (declare (type bignum-index ,@sizes)) ,@checks (let ,resallocs ;; copy GMP limbs into result bignum (sb-sys:with-pinned-objects ,results ,@copylimbs) ,@clears (values ,@results)))))))
On 03.05.2014 21:01, Stas Boukarev wrote: 153687 11) 153687 11)), so,
> I get a different result:
> (SB-GMP:MPZ-POW -15546163094340
>
[...]
>
> Which
>
> is equal to (ldb (byte 704 0) (expt -15546163094340
> there's a problem with sign extension.
>
Yes, replace with the follow macro; I haven't committed yet, because of
the strange results when requiring the test-suite:
(defmacro with-gmp- mpz-results (resultvars &body body) :maximum- bignum- length) )
( error "Size of result exceeds maxim bignum
;( gmp-z-to- bignum- neg (slot ,gres
(negate- bignum (gmp-z-to-bignum (slot
(gmp- z-to-bignum (slot ,gres 'mp_d)
`( with-alien ,declares
,@inits
,@body
(let ,resinits
(declare (type bignum-index ,@sizes))
,@checks
(let ,resallocs
;; copy GMP limbs into result bignum
(sb- sys:with- pinned- objects ,results
,@copylimbs)
,@ clears
(values ,@results)))))))
(loop for gres in resultvars
for res = (gensym "RESULT")
for size = (gensym "SIZE")
collect size into sizes
collect `(,gres (struct gmpint)) into declares
collect `(__gmpz_init (addr ,gres)) into inits
collect `(,size (1+ (abs (slot ,gres 'mp_size))))
into resinits
collect `(when (> ,size (1- sb-bignum:
length")) into checks
collect `(,res (%allocate-bignum (1+ ,size)))
into resallocs
collect `(setf ,res (if (minusp (slot ,gres 'mp_size)) ; check
for negative result
'mp_d) ,res ,size)
,gres 'mp_d) ,res ,size) nil)
,res ,size)))
into copylimbs
collect `(__gmpz_clear (addr ,gres)) into clears
collect res into results
finally (return