Implement 'exact-integer?' and 'scm_is_exact_integer'.
authorMark H Weaver <mhw@netris.org>
Fri, 20 Dec 2013 23:12:37 +0000 (18:12 -0500)
committerMark H Weaver <mhw@netris.org>
Thu, 9 Jan 2014 02:42:16 +0000 (21:42 -0500)
* 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.

doc/ref/api-data.texi
libguile/numbers.c
libguile/numbers.h
test-suite/tests/numbers.test

index 05469f7..fda76f1 100644 (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
 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
index 22b53a5..51e813a 100644 (file)
@@ -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)
 {
index 912f287..4d977dc 100644 (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_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,
index 16f06bf..e91bc52 100644 (file)
   (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?
 ;;;