From ce3ce21c623771ecafdf80c98519e80048cfedb7 Mon Sep 17 00:00:00 2001 From: Mark H Weaver Date: Tue, 8 Mar 2011 13:13:54 -0500 Subject: Improve docs of string and symbol conversions from C strings * doc/ref/api-data.texi (Conversion to/from C): Document scm_from_latin1_string, scm_from_utf8_string, and scm_from_utf32_string. Remind readers that these functions should be used to convert C string constants, and that scm_from_locale_string is _not_ appropriate for that purpose. (Symbol Primitives): Document scm_from_latin1_symbol and scm_from_utf8_symbol. Remind readers that these functions should be used when the specified names are C string constants, and that scm_from_locale_symbol is _not_ appropriate for that purpose. --- doc/ref/api-data.texi | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) (limited to 'doc/ref/api-data.texi') diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi index 5bef926a9..7fa38d18a 100644 --- a/doc/ref/api-data.texi +++ b/doc/ref/api-data.texi @@ -4182,6 +4182,12 @@ If @var{len} is @code{(size_t)-1}, then @var{str} does need to be null-terminated and the real length will be found with @code{strlen}. If the C string is ill-formed, an error will be raised. + +Note that these functions should @emph{not} be used to convert C string +constants, because there is no guarantee that the current locale will +match that of the source code. To convert C string constants, use +@code{scm_from_latin1_string}, @code{scm_from_utf8_string} or +@code{scm_from_utf32_string}. @end deftypefn @deftypefn {C Function} SCM scm_take_locale_string (char *str) @@ -4281,10 +4287,16 @@ The @var{handler} parameters suggests a strategy for dealing with unconvertable characters. @end deftypefn -ISO-8859-1 is the most common 8-bit character encoding. This encoding -is also referred to as the Latin-1 encoding. The following two -conversion functions are provided to convert between Latin-1 C strings -and Guile strings. +The following conversion functions are provided as a convenience for the +most commonly used encodings. + +@deftypefn {C Function} SCM scm_from_latin1_string (const char *str) +@deftypefnx {C Function} SCM scm_from_utf8_string (const char *str) +@deftypefnx {C Function} SCM scm_from_utf32_string (const scm_t_wchar *str) +Return a scheme string from the null-terminated C string @var{str}, +which is ISO-8859-1-, UTF-8-, or UTF-32-encoded. These functions should +be used to convert hard-coded C string constants into Scheme strings. +@end deftypefn @deftypefn {C Function} SCM scm_from_latin1_stringn (const char *str, size_t len) @deftypefnx {C Function} SCM scm_from_utf8_stringn (const char *str, size_t len) @@ -5218,12 +5230,24 @@ When you want to do more from C, you should convert between symbols and strings using @code{scm_symbol_to_string} and @code{scm_string_to_symbol} and work with the strings. +@deffn {C Function} scm_from_latin1_symbol (const char *name) +@deffnx {C Function} scm_from_utf8_symbol (const char *name) +Construct and return a Scheme symbol whose name is specified by the +null-terminated C string @var{name}. These are appropriate when +the C string is hard-coded in the source code. +@end deffn + @deffn {C Function} scm_from_locale_symbol (const char *name) @deffnx {C Function} scm_from_locale_symboln (const char *name, size_t len) Construct and return a Scheme symbol whose name is specified by @var{name}. For @code{scm_from_locale_symbol}, @var{name} must be null terminated; for @code{scm_from_locale_symboln} the length of @var{name} is specified explicitly by @var{len}. + +Note that these functions should @emph{not} be used when @var{name} is a +C string constant, because there is no guarantee that the current locale +will match that of the source code. In such cases, use +@code{scm_from_latin1_symbol} or @code{scm_from_utf8_symbol}. @end deffn @deftypefn {C Function} SCM scm_take_locale_symbol (char *str) -- cgit v1.2.3 From c428e58681fbd006d253bda51b3543110b317b8d Mon Sep 17 00:00:00 2001 From: Mark H Weaver Date: Wed, 9 Mar 2011 01:14:43 -0500 Subject: Add scm_from_latin1_keyword and scm_from_utf8_keyword * libguile/keywords.c (scm_from_latin1_keyword, scm_from_utf8_keyword): New functions appropriate for use when keyword name is a constant. (scm_from_locale_keyword, scm_from_locale_keywordn): Change formal parameter from `str' to `name'. * libguile/keywords.h: Add prototypes for new functions. Change formal parameter of scm_from_locale_keyword* from `str' to `name'. * doc/ref/api-data.texi: Document new functions. Remind users that scm_from_locale_keyword should not be used when the name is a C string constant. Change formal parameter from `str' to `name'. --- doc/ref/api-data.texi | 20 ++++++++++++++++---- libguile/keywords.c | 20 ++++++++++++++++---- libguile/keywords.h | 6 ++++-- 3 files changed, 36 insertions(+), 10 deletions(-) (limited to 'doc/ref/api-data.texi') diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi index 7fa38d18a..e519cab60 100644 --- a/doc/ref/api-data.texi +++ b/doc/ref/api-data.texi @@ -5730,11 +5730,23 @@ Return the keyword with the same name as @var{symbol}. Equivalent to @code{scm_is_true (scm_keyword_p (@var{obj}))}. @end deftypefn -@deftypefn {C Function} SCM scm_from_locale_keyword (const char *str) -@deftypefnx {C Function} SCM scm_from_locale_keywordn (const char *str, size_t len) +@deftypefn {C Function} SCM scm_from_locale_keyword (const char *name) +@deftypefnx {C Function} SCM scm_from_locale_keywordn (const char *name, size_t len) Equivalent to @code{scm_symbol_to_keyword (scm_from_locale_symbol -(@var{str}))} and @code{scm_symbol_to_keyword (scm_from_locale_symboln -(@var{str}, @var{len}))}, respectively. +(@var{name}))} and @code{scm_symbol_to_keyword (scm_from_locale_symboln +(@var{name}, @var{len}))}, respectively. + +Note that these functions should @emph{not} be used when @var{name} is a +C string constant, because there is no guarantee that the current locale +will match that of the source code. In such cases, use +@code{scm_from_latin1_keyword} or @code{scm_from_utf8_keyword}. +@end deftypefn + +@deftypefn {C Function} SCM scm_from_latin1_keyword (const char *name) +@deftypefnx {C Function} SCM scm_from_utf8_keyword (const char *name) +Equivalent to @code{scm_symbol_to_keyword (scm_from_latin1_symbol +(@var{name}))} and @code{scm_symbol_to_keyword (scm_from_utf8_symbol +(@var{name}))}, respectively. @end deftypefn @node Other Types diff --git a/libguile/keywords.c b/libguile/keywords.c index 0740801ae..3b9a9228c 100644 --- a/libguile/keywords.c +++ b/libguile/keywords.c @@ -101,15 +101,27 @@ scm_is_keyword (SCM val) } SCM -scm_from_locale_keyword (const char *str) +scm_from_locale_keyword (const char *name) { - return scm_symbol_to_keyword (scm_from_locale_symbol (str)); + return scm_symbol_to_keyword (scm_from_locale_symbol (name)); } SCM -scm_from_locale_keywordn (const char *str, size_t len) +scm_from_locale_keywordn (const char *name, size_t len) { - return scm_symbol_to_keyword (scm_from_locale_symboln (str, len)); + return scm_symbol_to_keyword (scm_from_locale_symboln (name, len)); +} + +SCM +scm_from_latin1_keyword (const char *name) +{ + return scm_symbol_to_keyword (scm_from_latin1_symbol (name)); +} + +SCM +scm_from_utf8_keyword (const char *name) +{ + return scm_symbol_to_keyword (scm_from_utf8_symbol (name)); } /* njrev: critical sections reviewed so far up to here */ diff --git a/libguile/keywords.h b/libguile/keywords.h index bfffe5923..c9e6af14b 100644 --- a/libguile/keywords.h +++ b/libguile/keywords.h @@ -36,8 +36,10 @@ SCM_API SCM scm_symbol_to_keyword (SCM symbol); SCM_API SCM scm_keyword_to_symbol (SCM keyword); SCM_API int scm_is_keyword (SCM val); -SCM_API SCM scm_from_locale_keyword (const char *str); -SCM_API SCM scm_from_locale_keywordn (const char *str, size_t len); +SCM_API SCM scm_from_locale_keyword (const char *name); +SCM_API SCM scm_from_locale_keywordn (const char *name, size_t len); +SCM_API SCM scm_from_latin1_keyword (const char *name); +SCM_API SCM scm_from_utf8_keyword (const char *name); SCM_INTERNAL void scm_init_keywords (void); -- cgit v1.2.3 From 95f5e303bc7f6174255b12fd1113d69364863762 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Thu, 17 Mar 2011 18:29:08 +0100 Subject: scm_{to,from}_locale_string use current locale, not current ports * libguile/strings.c (scm_to_locale_stringn, scm_from_locale_stringn): Use the encoding of the current locale, not of the current i/o ports. Also use the current conversion strategy. * doc/ref/api-data.texi (Conversion to/from C): Update docs. --- doc/ref/api-data.texi | 24 ++++++++++++------------ libguile/strings.c | 36 +++--------------------------------- 2 files changed, 15 insertions(+), 45 deletions(-) (limited to 'doc/ref/api-data.texi') diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi index e519cab60..0c4553f0e 100644 --- a/doc/ref/api-data.texi +++ b/doc/ref/api-data.texi @@ -4171,8 +4171,7 @@ using @code{scm_dynwind_free} inside an appropriate dynwind context, @deftypefn {C Function} SCM scm_from_locale_string (const char *str) @deftypefnx {C Function} SCM scm_from_locale_stringn (const char *str, size_t len) Creates a new Scheme string that has the same contents as @var{str} when -interpreted in the locale character encoding of the -@code{current-input-port}. +interpreted in the character encoding of the current locale. For @code{scm_from_locale_string}, @var{str} must be null-terminated. @@ -4201,9 +4200,9 @@ can then use @var{str} directly as its internal representation. @deftypefn {C Function} {char *} scm_to_locale_string (SCM str) @deftypefnx {C Function} {char *} scm_to_locale_stringn (SCM str, size_t *lenp) -Returns a C string with the same contents as @var{str} in the locale -encoding of the @code{current-output-port}. The C string must be freed -with @code{free} eventually, maybe by using @code{scm_dynwind_free}, +Returns a C string with the same contents as @var{str} in the character +encoding of the current locale. The C string must be freed with +@code{free} eventually, maybe by using @code{scm_dynwind_free}, @xref{Dynamic Wind}. For @code{scm_to_locale_string}, the returned string is @@ -4217,13 +4216,14 @@ returned string will not be null-terminated in this case. If @var{lenp} is @code{NULL}, @code{scm_to_locale_stringn} behaves like @code{scm_to_locale_string}. -If a character in @var{str} cannot be represented in the locale encoding -of the current output port, the port conversion strategy of the current -output port will determine the result, @xref{Ports}. If output port's -conversion strategy is @code{error}, an error will be raised. If it is -@code{substitute}, a replacement character, such as a question mark, will -be inserted in its place. If it is @code{escape}, a hex escape will be -inserted in its place. +If a character in @var{str} cannot be represented in the character +encoding of the current locale, the default port conversion strategy is +used. @xref{Ports}, for more on conversion strategies. + +If the conversion strategy is @code{error}, an error will be raised. If +it is @code{substitute}, a replacement character, such as a question +mark, will be inserted in its place. If it is @code{escape}, a hex +escape will be inserted in its place. @end deftypefn @deftypefn {C Function} size_t scm_to_locale_stringbuf (SCM str, char *buf, size_t max_len) diff --git a/libguile/strings.c b/libguile/strings.c index b13cb780f..6f4004b3d 100644 --- a/libguile/strings.c +++ b/libguile/strings.c @@ -1528,25 +1528,8 @@ scm_from_locale_string (const char *str) SCM scm_from_locale_stringn (const char *str, size_t len) { - const char *enc; - scm_t_string_failed_conversion_handler hndl; - SCM inport; - scm_t_port *pt; - - inport = scm_current_input_port (); - if (!SCM_UNBNDP (inport) && SCM_OPINPORTP (inport)) - { - pt = SCM_PTAB_ENTRY (inport); - enc = pt->encoding; - hndl = pt->ilseq_handler; - } - else - { - enc = NULL; - hndl = SCM_FAILED_CONVERSION_ERROR; - } - - return scm_from_stringn (str, len, enc, hndl); + return scm_from_stringn (str, len, locale_charset (), + scm_i_get_conversion_strategy (SCM_BOOL_F)); } SCM @@ -1771,21 +1754,8 @@ scm_to_locale_string (SCM str) char * scm_to_locale_stringn (SCM str, size_t *lenp) { - SCM outport; - scm_t_port *pt; - const char *enc; - - outport = scm_current_output_port (); - if (!SCM_UNBNDP (outport) && SCM_OPOUTPORTP (outport)) - { - pt = SCM_PTAB_ENTRY (outport); - enc = pt->encoding; - } - else - enc = NULL; - return scm_to_stringn (str, lenp, - enc, + locale_charset (), scm_i_get_conversion_strategy (SCM_BOOL_F)); } -- cgit v1.2.3 From ce6066065dda2cf1854f6a63324abb75dc0bc23f Mon Sep 17 00:00:00 2001 From: Mark H Weaver Date: Wed, 6 Apr 2011 13:00:34 -0400 Subject: Doc fix: quotient/remainder/modulo do not require exact arguments * doc/ref/api-data.texi (Arithmetic): `floor-remainder' is equivalent to the R5RS `modulo' when the arguments are integers. Previously, equivalence was claimed only for exact integers. Similarly for `truncate-quotient' and `truncate-remainder' compared with the R5RS `quotient' and `remainder'. --- doc/ref/api-data.texi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'doc/ref/api-data.texi') diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi index 0c4553f0e..2b407ea99 100644 --- a/doc/ref/api-data.texi +++ b/doc/ref/api-data.texi @@ -1308,7 +1308,7 @@ both @var{q} and @var{r}, and is more efficient than computing each separately. Note that @var{r}, if non-zero, will have the same sign as @var{y}. -When @var{x} and @var{y} are exact integers, @code{floor-remainder} is +When @var{x} and @var{y} are integers, @code{floor-remainder} is equivalent to the R5RS integer-only operator @code{modulo}. @lisp @@ -1365,7 +1365,7 @@ both @var{q} and @var{r}, and is more efficient than computing each separately. Note that @var{r}, if non-zero, will have the same sign as @var{x}. -When @var{x} and @var{y} are exact integers, these operators are +When @var{x} and @var{y} are integers, these operators are equivalent to the R5RS integer-only operators @code{quotient} and @code{remainder}. -- cgit v1.2.3 From 882c89636a2a4afa26cff17c7cdbc1d8c1cb2745 Mon Sep 17 00:00:00 2001 From: Mark H Weaver Date: Wed, 6 Apr 2011 15:09:42 -0400 Subject: Fix the R6RS exact-integer-sqrt and import into core guile * libguile/numbers.c (scm_exact_integer_sqrt): New C procedure to compute exact integer square root and remainder. (scm_i_exact_integer_sqrt): New Scheme procedure `exact-integer-sqrt' from the R6RS, imported into core guile. * libguile/numbers.h: Add prototypes. * module/rnrs/base.scm: Remove broken stub implementation, which would fail badly when applied to large integers. * doc/ref/api-data.texi: Add documentation. * doc/ref/r6rs.texi: Change documentation for `exact-integer-sqrt' to a stub that xrefs the core docs, as is done for other operations available in core. * test-suite/tests/numbers.test: Add tests. * NEWS: Add news entries. --- NEWS | 15 ++++++++++ doc/ref/api-data.texi | 12 ++++++++ doc/ref/r6rs.texi | 6 +--- libguile/numbers.c | 64 +++++++++++++++++++++++++++++++++++++++++++ libguile/numbers.h | 2 ++ module/rnrs/base.scm | 3 -- test-suite/tests/numbers.test | 48 ++++++++++++++++++++++++++++++++ 7 files changed, 142 insertions(+), 8 deletions(-) (limited to 'doc/ref/api-data.texi') diff --git a/NEWS b/NEWS index b53386a0b..206153ac4 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,21 @@ See the end for copying conditions. Please send Guile bug reports to bug-guile@gnu.org. +Changes in 2.0.1 (since 2.0.0): + +* New procedures (see the manual for details) + +** exact-integer-sqrt, imported into core from (rnrs base) + +* Bugs fixed + +** exact-integer-sqrt now handles large integers correctly + +exact-integer-sqrt now works correctly when applied to very large +integers (too large to be precisely represented by a C double). +It has also been imported into core from (rnrs base). + + Changes in 2.0.0 (changes since the 1.8.x series): * New modules (see the manual for details) diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi index 2b407ea99..760039a32 100644 --- a/doc/ref/api-data.texi +++ b/doc/ref/api-data.texi @@ -959,6 +959,18 @@ Return @var{n} raised to the integer exponent @end lisp @end deffn +@deftypefn {Scheme Procedure} {} exact-integer-sqrt @var{k} +@deftypefnx {C Function} void scm_exact_integer_sqrt (SCM @var{k}, SCM *@var{s}, SCM *@var{r}) +Return two exact non-negative integers @var{s} and @var{r} +such that @math{@var{k} = @var{s}^2 + @var{r}} and +@math{@var{s}^2 <= @var{k} < (@var{s} + 1)^2}. +An error is raised if @var{k} is not an exact non-negative integer. + +@lisp +(exact-integer-sqrt 10) @result{} 3 and 1 +@end lisp +@end deftypefn + @node Comparison @subsubsection Comparison Predicates @rnindex zero? diff --git a/doc/ref/r6rs.texi b/doc/ref/r6rs.texi index 8f8928659..bc569ed69 100644 --- a/doc/ref/r6rs.texi +++ b/doc/ref/r6rs.texi @@ -379,6 +379,7 @@ grouped below by the existing manual sections to which they correspond. @deffnx {Scheme Procedure} even? n @deffnx {Scheme Procedure} gcd x ... @deffnx {Scheme Procedure} lcm x ... +@deffnx {Scheme Procedure} exact-integer-sqrt k @xref{Integer Operations}, for documentation. @end deffn @@ -525,11 +526,6 @@ This is a consequence of the requirement that @end lisp @end deffn -@deffn {Scheme Procedure} exact-integer-sqrt k -This procedure returns two nonnegative integer objects @code{s} and -@code{r} such that k = s^2 + r and k < (s + 1)^2. -@end deffn - @deffn {Scheme Procedure} real-valued? obj @deffnx {Scheme Procedure} rational-valued? obj @deffnx {Scheme Procedure} integer-valued? obj diff --git a/libguile/numbers.c b/libguile/numbers.c index b4f224240..74753812b 100644 --- a/libguile/numbers.c +++ b/libguile/numbers.c @@ -9555,6 +9555,70 @@ SCM_PRIMITIVE_GENERIC (scm_exp, "exp", 1, 0, 0, #undef FUNC_NAME +SCM_DEFINE (scm_i_exact_integer_sqrt, "exact-integer-sqrt", 1, 0, 0, + (SCM k), + "Return two exact non-negative integers @var{s} and @var{r}\n" + "such that @math{@var{k} = @var{s}^2 + @var{r}} and\n" + "@math{@var{s}^2 <= @var{k} < (@var{s} + 1)^2}.\n" + "An error is raised if @var{k} is not an exact non-negative integer.\n" + "\n" + "@lisp\n" + "(exact-integer-sqrt 10) @result{} 3 and 1\n" + "@end lisp") +#define FUNC_NAME s_scm_i_exact_integer_sqrt +{ + SCM s, r; + + scm_exact_integer_sqrt (k, &s, &r); + return scm_values (scm_list_2 (s, r)); +} +#undef FUNC_NAME + +void +scm_exact_integer_sqrt (SCM k, SCM *sp, SCM *rp) +{ + if (SCM_LIKELY (SCM_I_INUMP (k))) + { + scm_t_inum kk = SCM_I_INUM (k); + scm_t_inum uu = kk; + scm_t_inum ss; + + if (SCM_LIKELY (kk > 0)) + { + do + { + ss = uu; + uu = (ss + kk/ss) / 2; + } while (uu < ss); + *sp = SCM_I_MAKINUM (ss); + *rp = SCM_I_MAKINUM (kk - ss*ss); + } + else if (SCM_LIKELY (kk == 0)) + *sp = *rp = SCM_INUM0; + else + scm_wrong_type_arg_msg ("exact-integer-sqrt", SCM_ARG1, k, + "exact non-negative integer"); + } + else if (SCM_LIKELY (SCM_BIGP (k))) + { + SCM s, r; + + if (mpz_sgn (SCM_I_BIG_MPZ (k)) < 0) + scm_wrong_type_arg_msg ("exact-integer-sqrt", SCM_ARG1, k, + "exact non-negative integer"); + s = scm_i_mkbig (); + r = scm_i_mkbig (); + mpz_sqrtrem (SCM_I_BIG_MPZ (s), SCM_I_BIG_MPZ (r), SCM_I_BIG_MPZ (k)); + scm_remember_upto_here_1 (k); + *sp = scm_i_normbig (s); + *rp = scm_i_normbig (r); + } + else + scm_wrong_type_arg_msg ("exact-integer-sqrt", SCM_ARG1, k, + "exact non-negative integer"); +} + + SCM_PRIMITIVE_GENERIC (scm_sqrt, "sqrt", 1, 0, 0, (SCM z), "Return the square root of @var{z}. Of the two possible roots\n" diff --git a/libguile/numbers.h b/libguile/numbers.h index ab96981c6..d98583039 100644 --- a/libguile/numbers.h +++ b/libguile/numbers.h @@ -289,6 +289,7 @@ SCM_API SCM scm_log (SCM z); SCM_API SCM scm_log10 (SCM z); SCM_API SCM scm_exp (SCM z); SCM_API SCM scm_sqrt (SCM z); +SCM_API void scm_exact_integer_sqrt (SCM k, SCM *s, SCM *r); SCM_INTERNAL SCM scm_i_min (SCM x, SCM y, SCM rest); SCM_INTERNAL SCM scm_i_max (SCM x, SCM y, SCM rest); @@ -296,6 +297,7 @@ SCM_INTERNAL SCM scm_i_sum (SCM x, SCM y, SCM rest); SCM_INTERNAL SCM scm_i_difference (SCM x, SCM y, SCM rest); SCM_INTERNAL SCM scm_i_product (SCM x, SCM y, SCM rest); SCM_INTERNAL SCM scm_i_divide (SCM x, SCM y, SCM rest); +SCM_INTERNAL SCM scm_i_exact_integer_sqrt (SCM k); /* bignum internal functions */ SCM_INTERNAL SCM scm_i_mkbig (void); diff --git a/module/rnrs/base.scm b/module/rnrs/base.scm index 2f5a218de..b9dddab0b 100644 --- a/module/rnrs/base.scm +++ b/module/rnrs/base.scm @@ -103,9 +103,6 @@ (let ((sym (car syms))) (and (symbol? sym) (symbol=?-internal (cdr syms) sym))))) - (define (exact-integer-sqrt x) - (let* ((s (exact (floor (sqrt x)))) (e (- x (* s s)))) (values s e))) - (define (real-valued? x) (and (complex? x) (zero? (imag-part x)))) diff --git a/test-suite/tests/numbers.test b/test-suite/tests/numbers.test index d94b6a14e..b1f3d8bc0 100644 --- a/test-suite/tests/numbers.test +++ b/test-suite/tests/numbers.test @@ -4546,6 +4546,54 @@ (pass-if (= #xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF (lognot #x-100000000000000000000000000000000)))) +;;; +;;; exact-integer-sqrt +;;; + +(with-test-prefix "exact-integer-sqrt" + (define (non-negative-exact-integer? k) + (and (integer? k) (exact? k) (>= k 0))) + + (define (test k) + (pass-if k (let-values (((s r) (exact-integer-sqrt k))) + (and (non-negative-exact-integer? s) + (non-negative-exact-integer? r) + (= k (+ r (* s s))) + (< k (* (1+ s) (1+ s))))))) + + (define (test-wrong-type-arg k) + (pass-if-exception k exception:wrong-type-arg + (let-values (((s r) (exact-integer-sqrt k))) + #t))) + + (pass-if (documented? exact-integer-sqrt)) + + (pass-if-exception "no args" exception:wrong-num-args + (exact-integer-sqrt)) + (pass-if-exception "two args" exception:wrong-num-args + (exact-integer-sqrt 123 456)) + + (test 0) + (test 1) + (test 9) + (test 10) + (test fixnum-max) + (test (1+ fixnum-max)) + (test (* fixnum-max fixnum-max)) + (test (+ 1 (* fixnum-max fixnum-max))) + (test (expt 10 100)) + (test (+ 3 (expt 10 100))) + + (test-wrong-type-arg -1) + (test-wrong-type-arg 1/9) + (test-wrong-type-arg fixnum-min) + (test-wrong-type-arg (1- fixnum-min)) + (test-wrong-type-arg 1.0) + (test-wrong-type-arg 1.5) + (test-wrong-type-arg "foo") + (test-wrong-type-arg 'foo)) + + ;;; ;;; sqrt ;;; -- cgit v1.2.3