1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 03:40:34 +02:00

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.
This commit is contained in:
Mark H Weaver 2013-12-20 18:12:37 -05:00
parent f659df4495
commit 900a897cd3
4 changed files with 72 additions and 4 deletions

View file

@ -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 written as @code{3.0} with an explicit decimal-point is inexact, but
it is also an integer. The functions @code{integer?} and 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_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 allow exact integers and thus report false. Likewise, the conversion
functions like @code{scm_to_signed_integer} only accept exact functions like @code{scm_to_signed_integer} only accept exact
integers. integers.
@ -333,7 +334,7 @@ will become exact fractions.)
@deffn {Scheme Procedure} integer? x @deffn {Scheme Procedure} integer? x
@deffnx {C Function} scm_integer_p (x) @deffnx {C Function} scm_integer_p (x)
Return @code{#t} if @var{x} is an exact or inexact integer number, else Return @code{#t} if @var{x} is an exact or inexact integer number, else
@code{#f}. return @code{#f}.
@lisp @lisp
(integer? 487) (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))}. This is equivalent to @code{scm_is_true (scm_integer_p (x))}.
@end deftypefn @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 @defvr {C Type} scm_t_int8
@defvrx {C Type} scm_t_uint8 @defvrx {C Type} scm_t_uint8
@defvrx {C Type} scm_t_int16 @defvrx {C Type} scm_t_int16

View file

@ -6515,8 +6515,8 @@ SCM_DEFINE (scm_rational_p, "rational?", 1, 0, 0,
SCM_DEFINE (scm_integer_p, "integer?", 1, 0, 0, SCM_DEFINE (scm_integer_p, "integer?", 1, 0, 0,
(SCM x), (SCM x),
"Return @code{#t} if @var{x} is an integer number, @code{#f}\n" "Return @code{#t} if @var{x} is an integer number,\n"
"else.") "else return @code{#f}.")
#define FUNC_NAME s_scm_integer_p #define FUNC_NAME s_scm_integer_p
{ {
if (SCM_I_INUMP (x) || SCM_BIGP (x)) if (SCM_I_INUMP (x) || SCM_BIGP (x))
@ -6531,6 +6531,19 @@ SCM_DEFINE (scm_integer_p, "integer?", 1, 0, 0,
} }
#undef FUNC_NAME #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 scm_i_num_eq_p (SCM, SCM, SCM);
SCM_PRIMITIVE_GENERIC (scm_i_num_eq_p, "=", 0, 2, 1, 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)); 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 int
scm_is_signed_integer (SCM val, scm_t_intmax min, scm_t_intmax max) scm_is_signed_integer (SCM val, scm_t_intmax min, scm_t_intmax max)
{ {

View file

@ -243,6 +243,7 @@ SCM_API SCM scm_complex_p (SCM x);
SCM_API SCM scm_real_p (SCM x); SCM_API SCM scm_real_p (SCM x);
SCM_API SCM scm_rational_p (SCM z); SCM_API SCM scm_rational_p (SCM z);
SCM_API SCM scm_integer_p (SCM x); 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 SCM scm_inexact_p (SCM x);
SCM_API int scm_is_inexact (SCM x); SCM_API int scm_is_inexact (SCM x);
SCM_API SCM scm_num_eq_p (SCM x, SCM y); 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 */ /* conversion functions for integers */
SCM_API int scm_is_integer (SCM val); 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_API int scm_is_signed_integer (SCM val,
scm_t_intmax min, scm_t_intmax max); scm_t_intmax min, scm_t_intmax max);
SCM_API int scm_is_unsigned_integer (SCM val, SCM_API int scm_is_unsigned_integer (SCM val,

View file

@ -1807,6 +1807,34 @@
(pass-if (not (integer? (lambda () #t)))) (pass-if (not (integer? (lambda () #t))))
(pass-if (not (integer? (current-input-port))))) (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? ;;; inexact?
;;; ;;;