From: Mark H Weaver Date: Fri, 20 Dec 2013 23:12:37 +0000 (-0500) Subject: Implement 'exact-integer?' and 'scm_is_exact_integer'. X-Git-Url: https://git.hcoop.net/bpt/guile.git/commitdiff_plain/900a897cd31df98df06b84a478b77a7438739b54 Implement 'exact-integer?' and 'scm_is_exact_integer'. * libguile/numbers.c (scm_exact_integer_p, scm_is_exact_integer): New procedures. (scm_integer_p): Improve docstring. * libguile/numbers.h (scm_exact_integer_p, scm_is_exact_integer): New prototypes. * doc/ref/api-data.texi (Integers): Add docs. * test-suite/tests/numbers.test ("exact-integer?"): Add tests. --- diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi index 05469f765..fda76f1dc 100644 --- a/doc/ref/api-data.texi +++ b/doc/ref/api-data.texi @@ -318,7 +318,8 @@ Scheme integers can be exact and inexact. For example, a number written as @code{3.0} with an explicit decimal-point is inexact, but it is also an integer. The functions @code{integer?} and @code{scm_is_integer} report true for such a number, but the functions -@code{scm_is_signed_integer} and @code{scm_is_unsigned_integer} only +@code{exact-integer?}, @code{scm_is_exact_integer}, +@code{scm_is_signed_integer}, and @code{scm_is_unsigned_integer} only allow exact integers and thus report false. Likewise, the conversion functions like @code{scm_to_signed_integer} only accept exact integers. @@ -333,7 +334,7 @@ will become exact fractions.) @deffn {Scheme Procedure} integer? x @deffnx {C Function} scm_integer_p (x) Return @code{#t} if @var{x} is an exact or inexact integer number, else -@code{#f}. +return @code{#f}. @lisp (integer? 487) @@ -354,6 +355,24 @@ Return @code{#t} if @var{x} is an exact or inexact integer number, else This is equivalent to @code{scm_is_true (scm_integer_p (x))}. @end deftypefn +@deffn {Scheme Procedure} exact-integer? x +@deffnx {C Function} scm_exact_integer_p (x) +Return @code{#t} if @var{x} is an exact integer number, else +return @code{#f}. + +@lisp +(exact-integer? 37) +@result{} #t + +(exact-integer? 3.0) +@result{} #f +@end lisp +@end deffn + +@deftypefn {C Function} int scm_is_exact_integer (SCM x) +This is equivalent to @code{scm_is_true (scm_exact_integer_p (x))}. +@end deftypefn + @defvr {C Type} scm_t_int8 @defvrx {C Type} scm_t_uint8 @defvrx {C Type} scm_t_int16 diff --git a/libguile/numbers.c b/libguile/numbers.c index 22b53a502..51e813ac9 100644 --- a/libguile/numbers.c +++ b/libguile/numbers.c @@ -6515,8 +6515,8 @@ SCM_DEFINE (scm_rational_p, "rational?", 1, 0, 0, SCM_DEFINE (scm_integer_p, "integer?", 1, 0, 0, (SCM x), - "Return @code{#t} if @var{x} is an integer number, @code{#f}\n" - "else.") + "Return @code{#t} if @var{x} is an integer number,\n" + "else return @code{#f}.") #define FUNC_NAME s_scm_integer_p { if (SCM_I_INUMP (x) || SCM_BIGP (x)) @@ -6531,6 +6531,19 @@ SCM_DEFINE (scm_integer_p, "integer?", 1, 0, 0, } #undef FUNC_NAME +SCM_DEFINE (scm_exact_integer_p, "exact-integer?", 1, 0, 0, + (SCM x), + "Return @code{#t} if @var{x} is an exact integer number,\n" + "else return @code{#f}.") +#define FUNC_NAME s_scm_exact_integer_p +{ + if (SCM_I_INUMP (x) || SCM_BIGP (x)) + return SCM_BOOL_T; + else + return SCM_BOOL_F; +} +#undef FUNC_NAME + SCM scm_i_num_eq_p (SCM, SCM, SCM); SCM_PRIMITIVE_GENERIC (scm_i_num_eq_p, "=", 0, 2, 1, @@ -9603,6 +9616,12 @@ scm_is_integer (SCM val) return scm_is_true (scm_integer_p (val)); } +int +scm_is_exact_integer (SCM val) +{ + return scm_is_true (scm_exact_integer_p (val)); +} + int scm_is_signed_integer (SCM val, scm_t_intmax min, scm_t_intmax max) { diff --git a/libguile/numbers.h b/libguile/numbers.h index 912f287bb..4d977dc3c 100644 --- a/libguile/numbers.h +++ b/libguile/numbers.h @@ -243,6 +243,7 @@ SCM_API SCM scm_complex_p (SCM x); SCM_API SCM scm_real_p (SCM x); SCM_API SCM scm_rational_p (SCM z); SCM_API SCM scm_integer_p (SCM x); +SCM_API SCM scm_exact_integer_p (SCM x); SCM_API SCM scm_inexact_p (SCM x); SCM_API int scm_is_inexact (SCM x); SCM_API SCM scm_num_eq_p (SCM x, SCM y); @@ -331,6 +332,7 @@ SCM_INTERNAL void scm_i_print_complex (double real, double imag, SCM port); /* conversion functions for integers */ SCM_API int scm_is_integer (SCM val); +SCM_API int scm_is_exact_integer (SCM val); SCM_API int scm_is_signed_integer (SCM val, scm_t_intmax min, scm_t_intmax max); SCM_API int scm_is_unsigned_integer (SCM val, diff --git a/test-suite/tests/numbers.test b/test-suite/tests/numbers.test index 16f06bf83..e91bc5240 100644 --- a/test-suite/tests/numbers.test +++ b/test-suite/tests/numbers.test @@ -1807,6 +1807,34 @@ (pass-if (not (integer? (lambda () #t)))) (pass-if (not (integer? (current-input-port))))) +;;; +;;; integer? +;;; + +(with-test-prefix "exact-integer?" + (pass-if (documented? exact-integer?)) + (pass-if (exact-integer? 0)) + (pass-if (exact-integer? 7)) + (pass-if (exact-integer? -7)) + (pass-if (exact-integer? (+ 1 fixnum-max))) + (pass-if (exact-integer? (- 1 fixnum-min))) + (pass-if (and (= 1.0 (round 1.0)) + (not (exact-integer? 1.0)))) + (pass-if (not (exact-integer? 1.3))) + (pass-if (not (exact-integer? +inf.0))) + (pass-if (not (exact-integer? -inf.0))) + (pass-if (not (exact-integer? +nan.0))) + (pass-if (not (exact-integer? +inf.0-inf.0i))) + (pass-if (not (exact-integer? +nan.0+nan.0i))) + (pass-if (not (exact-integer? 3+4i))) + (pass-if (not (exact-integer? #\a))) + (pass-if (not (exact-integer? "a"))) + (pass-if (not (exact-integer? (make-vector 0)))) + (pass-if (not (exact-integer? (cons 1 2)))) + (pass-if (not (exact-integer? #t))) + (pass-if (not (exact-integer? (lambda () #t)))) + (pass-if (not (exact-integer? (current-input-port))))) + ;;; ;;; inexact? ;;;