diff --git a/eval.c b/eval.c index 08a7e0a7..2ec932f5 100644 --- a/eval.c +++ b/eval.c @@ -1088,7 +1088,7 @@ static sexp sexp_sqrt (sexp ctx sexp_api_params(self, n), sexp z) { else return sexp_type_exception(ctx, self, SEXP_NUMBER, z); r = sqrt(d); - if (sexp_fixnump(z) && ((r*r) == (double)sexp_unbox_fixnum(z))) + if (sexp_fixnump(z) && (((sexp_uint_t)r*(sexp_uint_t)r)==sexp_unbox_fixnum(z))) return sexp_make_fixnum(round(r)); else return sexp_make_flonum(ctx, r); diff --git a/lib/init.scm b/lib/init.scm index 8ea2077b..d71570b5 100644 --- a/lib/init.scm +++ b/lib/init.scm @@ -419,8 +419,16 @@ (define real? number?) (define (exact? x) (if (fixnum? x) #t (bignum? x))) (define inexact? flonum?) +(define (exact-integer? x) (if (fixnum? x) #t (bignum? x))) (define (integer? x) - (if (fixnum? x) #t (if (bignum? x) #t (and (flonum? x) (= x (truncate x)))))) + (if (exact-integer? x) #t (and (flonum? x) (= x (truncate x))))) + +(define (exact-integer-sqrt x) + (let ((res (sqrt x))) + (if (exact? res) + (values res 0) + (let ((res (inexact->exact (truncate res)))) + (values res (- x (* res res))))))) (define (zero? x) (= x 0)) (define (positive? x) (> x 0))