1 /* Copyright (C) 1995,1996,1997,1998, 1999 Free Software Foundation, Inc.
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
40 * If you do not wish that, delete this exception notice. */
53 #define DIGITS '0':case '1':case '2':case '3':case '4':\
54 case '5':case '6':case '7':case '8':case '9'
57 /* IS_INF tests its floating point number for infiniteness
60 #define IS_INF(x) ((x) == (x) / 2)
63 /* Return true if X is not infinite and is not a NaN
66 #define isfinite(x) (!IS_INF (x) && (x) == (x))
69 /* MAXEXP is the maximum double precision expontent
70 * FLTMAX is less than or scm_equal the largest single precision float
77 #endif /* ndef GO32 */
78 #endif /* def STDC_HEADERS */
80 #define MAXEXP DBL_MAX_10_EXP
82 #define MAXEXP 308 /* IEEE doubles */
83 #endif /* def DBL_MAX_10_EXP */
85 #define FLTMAX FLT_MAX
88 #endif /* def FLT_MAX */
89 #endif /* def SCM_FLOATS */
93 SCM_PROC (s_exact_p
, "exact?", 1, 0, 0, scm_exact_p
);
102 if (SCM_NIMP (x
) && SCM_BIGP (x
))
108 SCM_PROC (s_odd_p
, "odd?", 1, 0, 0, scm_odd_p
);
117 SCM_ASSERT (SCM_NIMP (n
) && SCM_BIGP (n
), n
, SCM_ARG1
, s_odd_p
);
118 return (1 & SCM_BDIGITS (n
)[0]) ? SCM_BOOL_T
: SCM_BOOL_F
;
121 SCM_ASSERT (SCM_INUMP (n
), n
, SCM_ARG1
, s_odd_p
);
123 return (4 & (int) n
) ? SCM_BOOL_T
: SCM_BOOL_F
;
126 SCM_PROC (s_even_p
, "even?", 1, 0, 0, scm_even_p
);
135 SCM_ASSERT (SCM_NIMP (n
) && SCM_BIGP (n
), n
, SCM_ARG1
, s_even_p
);
136 return (1 & SCM_BDIGITS (n
)[0]) ? SCM_BOOL_F
: SCM_BOOL_T
;
139 SCM_ASSERT (SCM_INUMP (n
), n
, SCM_ARG1
, s_even_p
);
141 return (4 & (int) n
) ? SCM_BOOL_F
: SCM_BOOL_T
;
144 SCM_GPROC (s_abs
, "abs", 1, 0, 0, scm_abs
, g_abs
);
153 SCM_GASSERT1 (SCM_NIMP (x
) && SCM_BIGP (x
), g_abs
, x
, SCM_ARG1
, s_abs
);
154 if (SCM_TYP16 (x
) == scm_tc16_bigpos
)
156 return scm_copybig (x
, 0);
159 SCM_GASSERT1 (SCM_INUMP (x
), g_abs
, x
, SCM_ARG1
, s_abs
);
161 if (SCM_INUM (x
) >= 0)
164 if (!SCM_POSFIXABLE (x
))
166 return scm_long2big (x
);
168 scm_num_overflow (s_abs
);
170 return SCM_MAKINUM (x
);
173 SCM_GPROC (s_quotient
, "quotient", 2, 0, 0, scm_quotient
, g_quotient
);
185 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
186 g_quotient
, x
, y
, SCM_ARG1
, s_quotient
);
189 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
190 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
191 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
192 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
), 2);
202 w
= scm_copybig (x
, SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0));
203 scm_divbigdig (SCM_BDIGITS (w
), SCM_NUMDIGS (w
), (SCM_BIGDIG
) z
);
204 return scm_normbig (w
);
206 #ifndef SCM_DIGSTOOBIG
207 w
= scm_pseudolong (z
);
208 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
209 (SCM_BIGDIG
*) & w
, SCM_DIGSPERLONG
,
210 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 2);
213 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
214 scm_longdigs (z
, zdigs
);
215 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
216 zdigs
, SCM_DIGSPERLONG
,
217 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 2);
224 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
227 SCM_WTA_DISPATCH_2 (g_quotient
, x
, y
, SCM_ARG2
, s_quotient
);
233 SCM_GASSERT2 (SCM_INUMP (x
), g_quotient
, x
, y
, SCM_ARG1
, s_quotient
);
234 SCM_GASSERT2 (SCM_INUMP (y
), g_quotient
, x
, y
, SCM_ARG2
, s_quotient
);
236 if ((z
= SCM_INUM (y
)) == 0)
239 scm_num_overflow (s_quotient
);
241 z
= SCM_INUM (x
) / z
;
244 #if (__TURBOC__ == 1)
245 long t
= ((y
< 0) ? -SCM_INUM (x
) : SCM_INUM (x
)) % SCM_INUM (y
);
247 long t
= SCM_INUM (x
) % SCM_INUM (y
);
258 if (!SCM_FIXABLE (z
))
260 return scm_long2big (z
);
262 scm_num_overflow (s_quotient
);
264 return SCM_MAKINUM (z
);
267 SCM_GPROC (s_remainder
, "remainder", 2, 0, 0, scm_remainder
, g_remainder
);
278 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
279 g_remainder
, x
, y
, SCM_ARG1
, s_remainder
);
282 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
283 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
284 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
287 if (!(z
= SCM_INUM (y
)))
289 return scm_divbigint (x
, z
, SCM_BIGSIGN (x
), 0);
294 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
297 SCM_WTA_DISPATCH_2 (g_remainder
, x
, y
, SCM_ARG2
, s_remainder
);
303 SCM_GASSERT2 (SCM_INUMP (x
), g_remainder
, x
, y
, SCM_ARG1
, s_remainder
);
304 SCM_GASSERT2 (SCM_INUMP (y
), g_remainder
, x
, y
, SCM_ARG2
, s_remainder
);
306 if (!(z
= SCM_INUM (y
)))
309 scm_num_overflow (s_remainder
);
311 #if (__TURBOC__ == 1)
315 z
= SCM_INUM (x
) % z
;
325 return SCM_MAKINUM (z
);
328 SCM_GPROC (s_modulo
, "modulo", 2, 0, 0, scm_modulo
, g_modulo
);
339 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
340 g_modulo
, x
, y
, SCM_ARG1
, s_modulo
);
343 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
344 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
345 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
347 (SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
)) ? 1 : 0);
349 if (!(z
= SCM_INUM (y
)))
351 return scm_divbigint (x
, z
, y
< 0,
352 (SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0)) ? 1 : 0);
357 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
360 SCM_WTA_DISPATCH_2 (g_modulo
, x
, y
, SCM_ARG2
, s_modulo
);
363 return (SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0)) ? scm_sum (x
, y
) : x
;
366 SCM_GASSERT1 (SCM_INUMP (x
), g_modulo
, x
, y
, SCM_ARG1
, s_modulo
);
367 SCM_GASSERT2 (SCM_INUMP (y
), g_modulo
, x
, y
, SCM_ARG2
, s_modulo
);
369 if (!(yy
= SCM_INUM (y
)))
372 scm_num_overflow (s_modulo
);
376 z
= ((yy
< 0) ? -z
: z
) % yy
;
378 z
= SCM_INUM (x
) % yy
;
380 return SCM_MAKINUM (((yy
< 0) ? (z
> 0) : (z
< 0)) ? z
+ yy
: z
);
383 SCM_GPROC1 (s_gcd
, "gcd", scm_tc7_asubr
, scm_gcd
, g_gcd
);
390 register long u
, v
, k
, t
;
392 return SCM_UNBNDP (x
) ? SCM_INUM0
: x
;
398 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
399 g_gcd
, x
, y
, SCM_ARG1
, s_gcd
);
401 x
= scm_copybig (x
, 0);
405 SCM_GASSERT2 (SCM_NIMP (y
) && SCM_BIGP (y
),
406 g_gcd
, x
, y
, SCM_ARGn
, s_gcd
);
408 y
= scm_copybig (y
, 0);
409 switch (scm_bigcomp (x
, y
))
413 t
= scm_remainder (x
, y
);
420 y
= scm_remainder (y
, x
);
423 /* instead of the switch, we could just
424 return scm_gcd (y, scm_modulo (x, y)); */
438 SCM_GASSERT2 (SCM_INUMP (x
), g_gcd
, x
, y
, SCM_ARG1
, s_gcd
);
439 SCM_GASSERT2 (SCM_INUMP (y
), g_gcd
, x
, y
, SCM_ARGn
, s_gcd
);
454 for (k
= 1; !(1 & ((int) u
| (int) v
)); k
<<= 1, u
>>= 1, v
>>= 1);
473 if (!SCM_POSFIXABLE (u
))
475 return scm_long2big (u
);
477 scm_num_overflow (s_gcd
);
479 return SCM_MAKINUM (u
);
482 SCM_GPROC1 (s_lcm
, "lcm", scm_tc7_asubr
, scm_lcm
, g_lcm
);
491 SCM_GASSERT2 (SCM_INUMP (n1
) || SCM_UNBNDP (n1
),
492 g_lcm
, n1
, n2
, SCM_ARG1
, s_lcm
);
493 SCM_GASSERT2 (SCM_INUMP (n2
) || SCM_UNBNDP (n2
),
494 g_lcm
, n1
, n2
, SCM_ARGn
, s_lcm
);
496 SCM_GASSERT2 (SCM_INUMP (n1
)
498 || (SCM_NIMP (n1
) && SCM_BIGP (n1
)),
499 g_lcm
, n1
, n2
, SCM_ARG1
, s_lcm
);
500 SCM_GASSERT2 (SCM_INUMP (n2
)
502 || (SCM_NIMP (n2
) && SCM_BIGP (n2
)),
503 g_lcm
, n1
, n2
, SCM_ARGn
, s_lcm
);
507 n2
= SCM_MAKINUM (1L);
512 d
= scm_gcd (n1
, n2
);
515 return scm_abs (scm_product (n1
, scm_quotient (n2
, d
)));
520 #define scm_long2num SCM_MAKINUM
525 SCM_PROC1 (s_logand
, "logand", scm_tc7_asubr
, scm_logand
);
535 return SCM_MAKINUM (-1);
538 return scm_ulong2num (scm_num2ulong (n1
, (char *) SCM_ARG1
, s_logand
)
539 & scm_num2ulong (n2
, (char *) SCM_ARG2
, s_logand
));
542 SCM_PROC1 (s_logior
, "logior", scm_tc7_asubr
, scm_logior
);
555 return scm_ulong2num (scm_num2ulong (n1
, (char *) SCM_ARG1
, s_logior
)
556 | scm_num2ulong (n2
, (char *) SCM_ARG2
, s_logior
));
559 SCM_PROC1 (s_logxor
, "logxor", scm_tc7_asubr
, scm_logxor
);
572 return scm_ulong2num (scm_num2ulong (n1
, (char *) SCM_ARG1
, s_logxor
)
573 ^ scm_num2ulong (n2
, (char *) SCM_ARG2
, s_logxor
));
576 SCM_PROC (s_logtest
, "logtest", 2, 0, 0, scm_logtest
);
583 return ((scm_num2ulong (n1
, (char *) SCM_ARG1
, s_logtest
)
584 & scm_num2ulong (n2
, (char *) SCM_ARG2
, s_logtest
))
585 ? SCM_BOOL_T
: SCM_BOOL_F
);
589 SCM_PROC (s_logbit_p
, "logbit?", 2, 0, 0, scm_logbit_p
);
592 scm_logbit_p (n1
, n2
)
596 return (((1 << scm_num2long (n1
, (char *) SCM_ARG1
, s_logtest
))
597 & scm_num2ulong (n2
, (char *) SCM_ARG2
, s_logtest
))
598 ? SCM_BOOL_T
: SCM_BOOL_F
);
603 SCM_PROC1 (s_logand
, "logand", scm_tc7_asubr
, scm_logand
);
613 return SCM_MAKINUM (-1);
616 return SCM_MAKINUM (SCM_INUM (n1
) & SCM_INUM (n2
));
619 SCM_PROC1 (s_logior
, "logior", scm_tc7_asubr
, scm_logior
);
632 return SCM_MAKINUM (SCM_INUM (n1
) | SCM_INUM (n2
));
635 SCM_PROC1 (s_logxor
, "logxor", scm_tc7_asubr
, scm_logxor
);
648 return SCM_MAKINUM (SCM_INUM (n1
) ^ SCM_INUM (n2
));
651 SCM_PROC (s_logtest
, "logtest", 2, 0, 0, scm_logtest
);
658 SCM_ASSERT (SCM_INUMP (n1
), n1
, SCM_ARG1
, s_logtest
);
659 SCM_ASSERT (SCM_INUMP (n2
), n2
, SCM_ARG2
, s_logtest
);
660 return (SCM_INUM (n1
) & SCM_INUM (n2
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
663 SCM_PROC (s_logbit_p
, "logbit?", 2, 0, 0, scm_logbit_p
);
666 scm_logbit_p (n1
, n2
)
670 SCM_ASSERT (SCM_INUMP (n1
) && SCM_INUM (n1
) >= 0, n1
, SCM_ARG1
, s_logbit_p
);
671 SCM_ASSERT (SCM_INUMP (n2
), n2
, SCM_ARG2
, s_logbit_p
);
672 return ((1 << SCM_INUM (n1
)) & SCM_INUM (n2
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
676 SCM_PROC (s_lognot
, "lognot", 1, 0, 0, scm_lognot
);
682 SCM_ASSERT (SCM_INUMP (n
), n
, SCM_ARG1
, s_lognot
);
683 return scm_difference (SCM_MAKINUM (-1L), n
);
686 SCM_PROC (s_integer_expt
, "integer-expt", 2, 0, 0, scm_integer_expt
);
689 scm_integer_expt (z1
, z2
)
693 SCM acc
= SCM_MAKINUM (1L);
695 if (SCM_INUM0
== z1
|| acc
== z1
)
697 else if (SCM_MAKINUM (-1L) == z1
)
698 return SCM_BOOL_F
== scm_even_p (z2
) ? z1
: acc
;
700 SCM_ASSERT (SCM_INUMP (z2
), z2
, SCM_ARG2
, s_integer_expt
);
705 z1
= scm_divide (z1
, SCM_UNDEFINED
);
712 return scm_product (acc
, z1
);
714 acc
= scm_product (acc
, z1
);
715 z1
= scm_product (z1
, z1
);
720 SCM_PROC (s_ash
, "ash", 2, 0, 0, scm_ash
);
727 SCM res
= SCM_INUM (n
);
728 SCM_ASSERT (SCM_INUMP (cnt
), cnt
, SCM_ARG2
, s_ash
);
732 res
= scm_integer_expt (SCM_MAKINUM (2), SCM_MAKINUM (-SCM_INUM (cnt
)));
733 if (SCM_NFALSEP (scm_negative_p (n
)))
734 return scm_sum (SCM_MAKINUM (-1L),
735 scm_quotient (scm_sum (SCM_MAKINUM (1L), n
), res
));
737 return scm_quotient (n
, res
);
740 return scm_product (n
, scm_integer_expt (SCM_MAKINUM (2), cnt
));
742 SCM_ASSERT (SCM_INUMP (n
), n
, SCM_ARG1
, s_ash
);
743 cnt
= SCM_INUM (cnt
);
745 return SCM_MAKINUM (SCM_SRS (res
, -cnt
));
746 res
= SCM_MAKINUM (res
<< cnt
);
747 if (SCM_INUM (res
) >> cnt
!= SCM_INUM (n
))
748 scm_num_overflow (s_ash
);
753 SCM_PROC (s_bit_extract
, "bit-extract", 3, 0, 0, scm_bit_extract
);
756 scm_bit_extract (n
, start
, end
)
761 SCM_ASSERT (SCM_INUMP (start
), start
, SCM_ARG2
, s_bit_extract
);
762 SCM_ASSERT (SCM_INUMP (end
), end
, SCM_ARG3
, s_bit_extract
);
763 start
= SCM_INUM (start
);
764 end
= SCM_INUM (end
);
765 SCM_ASSERT (end
>= start
, SCM_MAKINUM (end
), SCM_OUTOFRANGE
, s_bit_extract
);
769 scm_logand (scm_difference (scm_integer_expt (SCM_MAKINUM (2),
770 SCM_MAKINUM (end
- start
)),
772 scm_ash (n
, SCM_MAKINUM (-start
)));
774 SCM_ASSERT (SCM_INUMP (n
), n
, SCM_ARG1
, s_bit_extract
);
776 return SCM_MAKINUM ((SCM_INUM (n
) >> start
) & ((1L << (end
- start
)) - 1));
779 static const char scm_logtab
[] = {
780 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
782 SCM_PROC (s_logcount
, "logcount", 1, 0, 0, scm_logcount
);
788 register unsigned long c
= 0;
795 SCM_ASSERT (SCM_NIMP (n
) && SCM_BIGP (n
), n
, SCM_ARG1
, s_logcount
);
797 return scm_logcount (scm_difference (SCM_MAKINUM (-1L), n
));
798 ds
= SCM_BDIGITS (n
);
799 for (i
= SCM_NUMDIGS (n
); i
--;)
800 for (d
= ds
[i
]; d
; d
>>= 4)
801 c
+= scm_logtab
[15 & d
];
802 return SCM_MAKINUM (c
);
805 SCM_ASSERT (SCM_INUMP (n
), n
, SCM_ARG1
, s_logcount
);
807 if ((nn
= SCM_INUM (n
)) < 0)
810 c
+= scm_logtab
[15 & nn
];
811 return SCM_MAKINUM (c
);
814 static const char scm_ilentab
[] = {
815 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
817 SCM_PROC (s_integer_length
, "integer-length", 1, 0, 0, scm_integer_length
);
820 scm_integer_length (n
)
823 register unsigned long c
= 0;
830 SCM_ASSERT (SCM_NIMP (n
) && SCM_BIGP (n
), n
, SCM_ARG1
, s_integer_length
);
832 return scm_integer_length (scm_difference (SCM_MAKINUM (-1L), n
));
833 ds
= SCM_BDIGITS (n
);
834 d
= ds
[c
= SCM_NUMDIGS (n
) - 1];
835 for (c
*= SCM_BITSPERDIG
; d
; d
>>= 4)
838 l
= scm_ilentab
[15 & d
];
840 return SCM_MAKINUM (c
- 4 + l
);
843 SCM_ASSERT (SCM_INUMP (n
), n
, SCM_ARG1
, s_integer_length
);
845 if ((nn
= SCM_INUM (n
)) < 0)
850 l
= scm_ilentab
[15 & nn
];
852 return SCM_MAKINUM (c
- 4 + l
);
857 static const char s_bignum
[] = "bignum";
860 scm_mkbig (nlen
, sign
)
865 /* Cast to SCM to avoid signed/unsigned comparison warnings. */
866 if (((v
<< 16) >> 16) != (SCM
) nlen
)
867 scm_wta (SCM_MAKINUM (nlen
), (char *) SCM_NALLOC
, s_bignum
);
870 SCM_SETCHARS (v
, scm_must_malloc ((long) (nlen
* sizeof (SCM_BIGDIG
)),
872 SCM_SETNUMDIGS (v
, nlen
, sign
? scm_tc16_bigneg
: scm_tc16_bigpos
);
883 unsigned long num
= 0;
884 SCM_BIGDIG
*tmp
= SCM_BDIGITS (b
);
886 num
= SCM_BIGUP (num
) + tmp
[l
];
887 if (SCM_TYP16 (b
) == scm_tc16_bigpos
)
889 if (SCM_POSFIXABLE (num
))
890 return SCM_MAKINUM (num
);
892 else if (SCM_UNEGFIXABLE (num
))
893 return SCM_MAKINUM (-num
);
898 static const char s_adjbig
[] = "scm_adjbig";
905 scm_sizet nsiz
= nlen
;
906 if (((nsiz
<< 16) >> 16) != nlen
)
907 scm_wta (scm_ulong2num (nsiz
), (char *) SCM_NALLOC
, s_adjbig
);
913 scm_must_realloc ((char *) SCM_CHARS (b
),
914 (long) (SCM_NUMDIGS (b
) * sizeof (SCM_BIGDIG
)),
915 (long) (nsiz
* sizeof (SCM_BIGDIG
)), s_adjbig
));
917 SCM_SETCHARS (b
, digits
);
918 SCM_SETNUMDIGS (b
, nsiz
, SCM_TYP16 (b
));
931 scm_sizet nlen
= SCM_NUMDIGS (b
);
933 int nlen
= SCM_NUMDIGS (b
); /* unsigned nlen breaks on Cray when nlen => 0 */
935 SCM_BIGDIG
*zds
= SCM_BDIGITS (b
);
936 while (nlen
-- && !zds
[nlen
]);
938 if (nlen
* SCM_BITSPERDIG
/ SCM_CHAR_BIT
<= sizeof (SCM
))
939 if (SCM_INUMP (b
= scm_big2inum (b
, (scm_sizet
) nlen
)))
941 if (SCM_NUMDIGS (b
) == nlen
)
943 return scm_adjbig (b
, (scm_sizet
) nlen
);
949 scm_copybig (b
, sign
)
953 scm_sizet i
= SCM_NUMDIGS (b
);
954 SCM ans
= scm_mkbig (i
, sign
);
955 SCM_BIGDIG
*src
= SCM_BDIGITS (b
), *dst
= SCM_BDIGITS (ans
);
969 SCM ans
= scm_mkbig (SCM_DIGSPERLONG
, n
< 0);
970 digits
= SCM_BDIGITS (ans
);
973 while (i
< SCM_DIGSPERLONG
)
975 digits
[i
++] = SCM_BIGLO (n
);
976 n
= SCM_BIGDN ((unsigned long) n
);
984 scm_long_long2big (n
)
995 if ((long long) tn
== n
)
996 return scm_long2big (tn
);
1002 for (tn
= n
, n_digits
= 0;
1004 ++n_digits
, tn
= SCM_BIGDN ((ulong_long
) tn
))
1009 ans
= scm_mkbig (n_digits
, n
< 0);
1010 digits
= SCM_BDIGITS (ans
);
1013 while (i
< n_digits
)
1015 digits
[i
++] = SCM_BIGLO (n
);
1016 n
= SCM_BIGDN ((ulong_long
) n
);
1032 ans
= scm_mkbig (2 * SCM_DIGSPERLONG
, 0);
1033 digits
= SCM_BDIGITS (ans
);
1036 for (i
= 0; i
< SCM_DIGSPERLONG
; ++i
)
1038 digits
[i
] = SCM_BIGLO (n
);
1039 n
= SCM_BIGDN ((unsigned long) n
);
1042 for (i
= 0; i
< SCM_DIGSPERLONG
; ++i
)
1044 digits
[i
+ SCM_DIGSPERLONG
] = SCM_BIGLO (n
);
1045 n
= SCM_BIGDN ((unsigned long) n
);
1058 SCM ans
= scm_mkbig (SCM_DIGSPERLONG
, 0);
1059 digits
= SCM_BDIGITS (ans
);
1060 while (i
< SCM_DIGSPERLONG
)
1062 digits
[i
++] = SCM_BIGLO (n
);
1075 int xsign
= SCM_BIGSIGN (x
);
1076 int ysign
= SCM_BIGSIGN (y
);
1077 scm_sizet xlen
, ylen
;
1079 /* Look at the signs, first. */
1085 /* They're the same sign, so see which one has more digits. Note
1086 that, if they are negative, the longer number is the lesser. */
1087 ylen
= SCM_NUMDIGS (y
);
1088 xlen
= SCM_NUMDIGS (x
);
1090 return (xsign
) ? -1 : 1;
1092 return (xsign
) ? 1 : -1;
1094 /* They have the same number of digits, so find the most significant
1095 digit where they differ. */
1099 if (SCM_BDIGITS (y
)[xlen
] != SCM_BDIGITS (x
)[xlen
])
1100 /* Make the discrimination based on the digit that differs. */
1101 return ((SCM_BDIGITS (y
)[xlen
] > SCM_BDIGITS (x
)[xlen
])
1103 : (xsign
? 1 : -1));
1106 /* The numbers are identical. */
1110 #ifndef SCM_DIGSTOOBIG
1120 SCM_BIGDIG bd
[SCM_DIGSPERLONG
];
1126 while (i
< SCM_DIGSPERLONG
)
1128 p
.bd
[i
++] = SCM_BIGLO (x
);
1131 /* p.bd[0] = SCM_BIGLO(x); p.bd[1] = SCM_BIGDN(x); */
1139 scm_longdigs (x
, digs
)
1146 while (i
< SCM_DIGSPERLONG
)
1148 digs
[i
++] = SCM_BIGLO (x
);
1157 scm_addbig (x
, nx
, xsgn
, bigy
, sgny
)
1164 /* Assumes nx <= SCM_NUMDIGS(bigy) */
1165 /* Assumes xsgn and sgny scm_equal either 0 or 0x0100 */
1167 scm_sizet i
= 0, ny
= SCM_NUMDIGS (bigy
);
1168 SCM z
= scm_copybig (bigy
, SCM_BIGSIGN (bigy
) ^ sgny
);
1169 SCM_BIGDIG
*zds
= SCM_BDIGITS (z
);
1170 if (xsgn
^ SCM_BIGSIGN (z
))
1174 num
+= (long) zds
[i
] - x
[i
];
1177 zds
[i
] = num
+ SCM_BIGRAD
;
1182 zds
[i
] = SCM_BIGLO (num
);
1187 if (num
&& nx
== ny
)
1191 SCM_SETCAR (z
, SCM_CAR (z
) ^ 0x0100);
1194 num
+= (SCM_BIGRAD
- 1) - zds
[i
];
1195 zds
[i
++] = SCM_BIGLO (num
);
1196 num
= SCM_BIGDN (num
);
1206 zds
[i
++] = num
+ SCM_BIGRAD
;
1211 zds
[i
++] = SCM_BIGLO (num
);
1220 num
+= (long) zds
[i
] + x
[i
];
1221 zds
[i
++] = SCM_BIGLO (num
);
1222 num
= SCM_BIGDN (num
);
1230 zds
[i
++] = SCM_BIGLO (num
);
1231 num
= SCM_BIGDN (num
);
1237 z
= scm_adjbig (z
, ny
+ 1);
1238 SCM_BDIGITS (z
)[ny
] = num
;
1242 return scm_normbig (z
);
1247 scm_mulbig (x
, nx
, y
, ny
, sgn
)
1254 scm_sizet i
= 0, j
= nx
+ ny
;
1255 unsigned long n
= 0;
1256 SCM z
= scm_mkbig (j
, sgn
);
1257 SCM_BIGDIG
*zds
= SCM_BDIGITS (z
);
1267 n
+= zds
[i
+ j
] + ((unsigned long) x
[i
] * y
[j
]);
1268 zds
[i
+ j
++] = SCM_BIGLO (n
);
1280 return scm_normbig (z
);
1284 /* Sun's compiler complains about the fact that this function has an
1285 ANSI prototype in numbers.h, but a K&R declaration here, and the
1286 two specify different promotions for the third argument. I'm going
1287 to turn this into an ANSI declaration, and see if anyone complains
1288 about it not being K&R. */
1291 scm_divbigdig (SCM_BIGDIG
* ds
,
1295 register unsigned long t2
= 0;
1298 t2
= SCM_BIGUP (t2
) + ds
[h
];
1308 scm_divbigint (x
, z
, sgn
, mode
)
1318 register unsigned long t2
= 0;
1319 register SCM_BIGDIG
*ds
= SCM_BDIGITS (x
);
1320 scm_sizet nd
= SCM_NUMDIGS (x
);
1322 t2
= (SCM_BIGUP (t2
) + ds
[nd
]) % z
;
1325 return SCM_MAKINUM (sgn
? -t2
: t2
);
1328 #ifndef SCM_DIGSTOOBIG
1329 unsigned long t2
= scm_pseudolong (z
);
1330 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
1331 (SCM_BIGDIG
*) & t2
, SCM_DIGSPERLONG
,
1334 SCM_BIGDIG t2
[SCM_DIGSPERLONG
];
1335 scm_longdigs (z
, t2
);
1336 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
1337 t2
, SCM_DIGSPERLONG
,
1345 scm_divbigbig (x
, nx
, y
, ny
, sgn
, modes
)
1353 /* modes description
1357 3 quotient but returns 0 if division is not exact. */
1358 scm_sizet i
= 0, j
= 0;
1360 unsigned long t2
= 0;
1362 SCM_BIGDIG d
= 0, qhat
, *zds
, *yds
;
1363 /* algorithm requires nx >= ny */
1367 case 0: /* remainder -- just return x */
1368 z
= scm_mkbig (nx
, sgn
);
1369 zds
= SCM_BDIGITS (z
);
1376 case 1: /* scm_modulo -- return y-x */
1377 z
= scm_mkbig (ny
, sgn
);
1378 zds
= SCM_BDIGITS (z
);
1381 num
+= (long) y
[i
] - x
[i
];
1384 zds
[i
] = num
+ SCM_BIGRAD
;
1399 zds
[i
++] = num
+ SCM_BIGRAD
;
1410 return SCM_INUM0
; /* quotient is zero */
1412 return 0; /* the division is not exact */
1415 z
= scm_mkbig (nx
== ny
? nx
+ 2 : nx
+ 1, sgn
);
1416 zds
= SCM_BDIGITS (z
);
1420 ny
--; /* in case y came in as a psuedolong */
1421 if (y
[ny
- 1] < (SCM_BIGRAD
>> 1))
1422 { /* normalize operands */
1423 d
= SCM_BIGRAD
/ (y
[ny
- 1] + 1);
1424 newy
= scm_mkbig (ny
, 0);
1425 yds
= SCM_BDIGITS (newy
);
1428 t2
+= (unsigned long) y
[j
] * d
;
1429 yds
[j
++] = SCM_BIGLO (t2
);
1430 t2
= SCM_BIGDN (t2
);
1437 t2
+= (unsigned long) x
[j
] * d
;
1438 zds
[j
++] = SCM_BIGLO (t2
);
1439 t2
= SCM_BIGDN (t2
);
1449 j
= nx
== ny
? nx
+ 1 : nx
; /* dividend needs more digits than divisor */
1451 { /* loop over digits of quotient */
1452 if (zds
[j
] == y
[ny
- 1])
1453 qhat
= SCM_BIGRAD
- 1;
1455 qhat
= (SCM_BIGUP (zds
[j
]) + zds
[j
- 1]) / y
[ny
- 1];
1462 { /* multiply and subtract */
1463 t2
+= (unsigned long) y
[i
] * qhat
;
1464 num
+= zds
[j
- ny
+ i
] - SCM_BIGLO (t2
);
1467 zds
[j
- ny
+ i
] = num
+ SCM_BIGRAD
;
1472 zds
[j
- ny
+ i
] = num
;
1475 t2
= SCM_BIGDN (t2
);
1478 num
+= zds
[j
- ny
+ i
] - t2
; /* borrow from high digit; don't update */
1480 { /* "add back" required */
1486 num
+= (long) zds
[j
- ny
+ i
] + y
[i
];
1487 zds
[j
- ny
+ i
] = SCM_BIGLO (num
);
1488 num
= SCM_BIGDN (num
);
1499 case 3: /* check that remainder==0 */
1500 for (j
= ny
; j
&& !zds
[j
- 1]; --j
);
1503 case 2: /* move quotient down in z */
1504 j
= (nx
== ny
? nx
+ 2 : nx
+ 1) - ny
;
1505 for (i
= 0; i
< j
; i
++)
1506 zds
[i
] = zds
[i
+ ny
];
1509 case 1: /* subtract for scm_modulo */
1515 num
+= y
[i
] - zds
[i
];
1519 zds
[i
] = num
+ SCM_BIGRAD
;
1531 case 0: /* just normalize remainder */
1533 scm_divbigdig (zds
, ny
, d
);
1536 for (j
= ny
; j
&& !zds
[j
- 1]; --j
);
1537 if (j
* SCM_BITSPERDIG
<= sizeof (SCM
) * SCM_CHAR_BIT
)
1538 if (SCM_INUMP (z
= scm_big2inum (z
, j
)))
1540 return scm_adjbig (z
, j
);
1548 /*** NUMBERS -> STRINGS ***/
1551 static const double fx
[] =
1552 { 0.0, 5e-1, 5e-2, 5e-3, 5e-4, 5e-5,
1553 5e-6, 5e-7, 5e-8, 5e-9, 5e-10,
1554 5e-11, 5e-12, 5e-13, 5e-14, 5e-15,
1555 5e-16, 5e-17, 5e-18, 5e-19, 5e-20};
1560 static scm_sizet idbl2str
SCM_P ((double f
, char *a
));
1567 int efmt
, dpt
, d
, i
, wp
= scm_dblprec
;
1572 goto zero
; /*{a[0]='0'; a[1]='.'; a[2]='0'; return 3;} */
1591 #ifdef DBL_MIN_10_EXP /* Prevent unnormalized values, as from
1592 make-uniform-vector, from causing infinite loops. */
1596 if (exp
-- < DBL_MIN_10_EXP
)
1602 if (exp
++ > DBL_MAX_10_EXP
)
1617 if (f
+ fx
[wp
] >= 10.0)
1624 dpt
= (exp
+ 9999) % 3;
1628 efmt
= (exp
< -3) || (exp
> wp
+ 2);
1653 if (f
+ fx
[wp
] >= 1.0)
1667 if ((dpt
> 4) && (exp
> 6))
1669 d
= (a
[0] == '-' ? 2 : 1);
1670 for (i
= ch
++; i
> d
; i
--)
1683 if (a
[ch
- 1] == '.')
1684 a
[ch
++] = '0'; /* trailing zero */
1693 for (i
= 10; i
<= exp
; i
*= 10);
1694 for (i
/= 10; i
; i
/= 10)
1696 a
[ch
++] = exp
/ i
+ '0';
1704 static scm_sizet iflo2str
SCM_P ((SCM flt
, char *str
));
1713 if (SCM_SINGP (flt
))
1714 i
= idbl2str (SCM_FLO (flt
), str
);
1717 i
= idbl2str (SCM_REAL (flt
), str
);
1718 if (SCM_CPLXP (flt
))
1720 if (0 <= SCM_IMAG (flt
)) /* jeh */
1721 str
[i
++] = '+'; /* jeh */
1722 i
+= idbl2str (SCM_IMAG (flt
), &str
[i
]);
1727 #endif /* SCM_FLOATS */
1731 scm_iint2str (num
, rad
, p
)
1737 register int i
= 1, d
;
1738 register long n
= num
;
1744 for (n
/= rad
; n
> 0; n
/= rad
)
1758 p
[i
] = d
+ ((d
< 10) ? '0' : 'a' - 10);
1766 static SCM big2str
SCM_P ((SCM b
, register unsigned int radix
));
1771 register unsigned int radix
;
1773 SCM t
= scm_copybig (b
, 0); /* sign of temp doesn't matter */
1774 register SCM_BIGDIG
*ds
= SCM_BDIGITS (t
);
1775 scm_sizet i
= SCM_NUMDIGS (t
);
1776 scm_sizet j
= radix
== 16 ? (SCM_BITSPERDIG
* i
) / 4 + 2
1777 : radix
>= 10 ? (SCM_BITSPERDIG
* i
* 241L) / 800 + 2
1778 : (SCM_BITSPERDIG
* i
) + 2;
1780 scm_sizet radct
= 0;
1781 scm_sizet ch
; /* jeh */
1782 SCM_BIGDIG radpow
= 1, radmod
= 0;
1783 SCM ss
= scm_makstr ((long) j
, 0);
1784 char *s
= SCM_CHARS (ss
), c
;
1785 while ((long) radpow
* radix
< SCM_BIGRAD
)
1790 s
[0] = scm_tc16_bigneg
== SCM_TYP16 (b
) ? '-' : '+';
1791 while ((i
|| radmod
) && j
)
1795 radmod
= (SCM_BIGDIG
) scm_divbigdig (ds
, i
, radpow
);
1803 s
[--j
] = c
< 10 ? c
+ '0' : c
+ 'a' - 10;
1805 ch
= s
[0] == '-' ? 1 : 0; /* jeh */
1808 for (i
= j
; j
< SCM_LENGTH (ss
); j
++)
1809 s
[ch
+ j
- i
] = s
[j
]; /* jeh */
1810 scm_vector_set_length_x (ss
, /* jeh */
1811 (SCM
) SCM_MAKINUM (ch
+ SCM_LENGTH (ss
) - i
));
1814 return scm_return_first (ss
, t
);
1819 SCM_PROC (s_number_to_string
, "number->string", 1, 1, 0, scm_number_to_string
);
1822 scm_number_to_string (x
, radix
)
1826 if (SCM_UNBNDP (radix
))
1827 radix
= SCM_MAKINUM (10L);
1829 SCM_ASSERT (SCM_INUMP (radix
), radix
, SCM_ARG2
, s_number_to_string
);
1833 char num_buf
[SCM_FLOBUFLEN
];
1835 SCM_ASRTGO (SCM_NIMP (x
), badx
);
1837 return big2str (x
, (unsigned int) SCM_INUM (radix
));
1838 #ifndef SCM_RECKLESS
1839 if (!(SCM_INEXP (x
)))
1842 scm_wta (x
, (char *) SCM_ARG1
, s_number_to_string
);
1846 SCM_ASSERT (SCM_NIMP (x
) && SCM_INEXP (x
),
1847 x
, SCM_ARG1
, s_number_to_string
);
1849 return scm_makfromstr (num_buf
, iflo2str (x
, num_buf
), 0);
1855 SCM_ASSERT (SCM_NIMP (x
) && SCM_BIGP (x
),
1856 x
, SCM_ARG1
, s_number_to_string
);
1857 return big2str (x
, (unsigned int) SCM_INUM (radix
));
1860 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_number_to_string
);
1864 char num_buf
[SCM_INTBUFLEN
];
1865 return scm_makfromstr (num_buf
,
1866 scm_iint2str (SCM_INUM (x
),
1867 (int) SCM_INUM (radix
),
1874 /* These print routines are stubbed here so that scm_repl.c doesn't need
1875 SCM_FLOATS or SCM_BIGDIGs conditionals */
1878 scm_floprint (sexp
, port
, pstate
)
1881 scm_print_state
*pstate
;
1884 char num_buf
[SCM_FLOBUFLEN
];
1885 scm_lfwrite (num_buf
, iflo2str (sexp
, num_buf
), port
);
1887 scm_ipruk ("float", sexp
, port
);
1895 scm_bigprint (exp
, port
, pstate
)
1898 scm_print_state
*pstate
;
1901 exp
= big2str (exp
, (unsigned int) 10);
1902 scm_lfwrite (SCM_CHARS (exp
), (scm_sizet
) SCM_LENGTH (exp
), port
);
1904 scm_ipruk ("bignum", exp
, port
);
1908 /*** END nums->strs ***/
1910 /*** STRINGS -> NUMBERS ***/
1912 static SCM scm_small_istr2int
SCM_P ((char *str
, long len
, long radix
));
1915 scm_small_istr2int (str
, len
, radix
)
1920 register long n
= 0, ln
;
1925 return SCM_BOOL_F
; /* zero scm_length */
1927 { /* leading sign */
1932 return SCM_BOOL_F
; /* bad if lone `+' or `-' */
1937 switch (c
= str
[i
++])
1959 return SCM_BOOL_F
; /* bad digit for radix */
1962 /* Negation is a workaround for HP700 cc bug */
1963 if (n
> ln
|| (-n
> -SCM_MOST_NEGATIVE_FIXNUM
))
1967 return SCM_BOOL_F
; /* not a digit */
1972 if ((n
= -n
) > SCM_MOST_POSITIVE_FIXNUM
)
1974 return SCM_MAKINUM (n
);
1975 ovfl
: /* overflow scheme integer */
1982 scm_istr2int (str
, len
, radix
)
1988 register scm_sizet k
, blen
= 1;
1992 register SCM_BIGDIG
*ds
;
1993 register unsigned long t2
;
1996 return SCM_BOOL_F
; /* zero scm_length */
1998 /* Short numbers we parse directly into an int, to avoid the overhead
1999 of creating a bignum. */
2001 return scm_small_istr2int (str
, len
, radix
);
2004 j
= 1 + (4 * len
* sizeof (char)) / (SCM_BITSPERDIG
);
2005 else if (10 <= radix
)
2006 j
= 1 + (84 * len
* sizeof (char)) / (SCM_BITSPERDIG
* 25);
2008 j
= 1 + (len
* sizeof (char)) / (SCM_BITSPERDIG
);
2010 { /* leading sign */
2013 if (++i
== (unsigned) len
)
2014 return SCM_BOOL_F
; /* bad if lone `+' or `-' */
2016 res
= scm_mkbig (j
, '-' == str
[0]);
2017 ds
= SCM_BDIGITS (res
);
2022 switch (c
= str
[i
++])
2044 return SCM_BOOL_F
; /* bad digit for radix */
2050 /* printf ("k = %d, blen = %d, t2 = %ld, ds[k] = %d\n", k, blen, t2, ds[k]); */
2051 t2
+= ds
[k
] * radix
;
2052 ds
[k
++] = SCM_BIGLO (t2
);
2053 t2
= SCM_BIGDN (t2
);
2056 scm_num_overflow ("bignum");
2064 return SCM_BOOL_F
; /* not a digit */
2067 while (i
< (unsigned) len
);
2068 if (blen
* SCM_BITSPERDIG
/ SCM_CHAR_BIT
<= sizeof (SCM
))
2069 if (SCM_INUMP (res
= scm_big2inum (res
, blen
)))
2073 return scm_adjbig (res
, blen
);
2079 scm_istr2flo (str
, len
, radix
)
2084 register int c
, i
= 0;
2086 double res
= 0.0, tmp
= 0.0;
2092 return SCM_BOOL_F
; /* zero scm_length */
2095 { /* leading sign */
2108 return SCM_BOOL_F
; /* bad if lone `+' or `-' */
2110 if (str
[i
] == 'i' || str
[i
] == 'I')
2111 { /* handle `+i' and `-i' */
2112 if (lead_sgn
== 0.0)
2113 return SCM_BOOL_F
; /* must have leading sign */
2115 return SCM_BOOL_F
; /* `i' not last character */
2116 return scm_makdbl (0.0, lead_sgn
);
2119 { /* check initial digits */
2129 goto out1
; /* must be exponent */
2146 return SCM_BOOL_F
; /* bad digit for radix */
2147 res
= res
* radix
+ c
;
2148 flg
= 1; /* res is valid */
2157 /* if true, then we did see a digit above, and res is valid */
2161 /* By here, must have seen a digit,
2162 or must have next char be a `.' with radix==10 */
2164 if (!(str
[i
] == '.' && radix
== 10))
2167 while (str
[i
] == '#')
2168 { /* optional sharps */
2201 tmp
= tmp
* radix
+ c
;
2209 return SCM_BOOL_F
; /* `slash zero' not allowed */
2211 while (str
[i
] == '#')
2212 { /* optional sharps */
2222 { /* decimal point notation */
2224 return SCM_BOOL_F
; /* must be radix 10 */
2231 res
= res
* 10.0 + c
- '0';
2240 return SCM_BOOL_F
; /* no digits before or after decimal point */
2243 while (str
[i
] == '#')
2244 { /* ignore remaining sharps */
2263 int expsgn
= 1, expon
= 0;
2265 return SCM_BOOL_F
; /* only in radix 10 */
2267 return SCM_BOOL_F
; /* bad exponent */
2274 return SCM_BOOL_F
; /* bad exponent */
2276 if (str
[i
] < '0' || str
[i
] > '9')
2277 return SCM_BOOL_F
; /* bad exponent */
2283 expon
= expon
* 10 + c
- '0';
2285 return SCM_BOOL_F
; /* exponent too large */
2293 point
+= expsgn
* expon
;
2311 /* at this point, we have a legitimate floating point result */
2312 if (lead_sgn
== -1.0)
2315 return scm_makdbl (res
, 0.0);
2317 if (str
[i
] == 'i' || str
[i
] == 'I')
2318 { /* pure imaginary number */
2319 if (lead_sgn
== 0.0)
2320 return SCM_BOOL_F
; /* must have leading sign */
2322 return SCM_BOOL_F
; /* `i' not last character */
2323 return scm_makdbl (0.0, res
);
2335 { /* polar input for complex number */
2336 /* get a `real' for scm_angle */
2337 second
= scm_istr2flo (&str
[i
], (long) (len
- i
), radix
);
2338 if (!(SCM_NIMP (second
) && SCM_INEXP (second
)))
2339 return SCM_BOOL_F
; /* not `real' */
2340 if (SCM_CPLXP (second
))
2341 return SCM_BOOL_F
; /* not `real' */
2342 tmp
= SCM_REALPART (second
);
2343 return scm_makdbl (res
* cos (tmp
), res
* sin (tmp
));
2349 /* at this point, last char must be `i' */
2350 if (str
[len
- 1] != 'i' && str
[len
- 1] != 'I')
2352 /* handles `x+i' and `x-i' */
2354 return scm_makdbl (res
, lead_sgn
);
2355 /* get a `ureal' for complex part */
2356 second
= scm_istr2flo (&str
[i
], (long) ((len
- i
) - 1), radix
);
2357 if (! (SCM_NIMP (second
) && SCM_INEXP (second
)))
2358 return SCM_BOOL_F
; /* not `ureal' */
2359 if (SCM_CPLXP (second
))
2360 return SCM_BOOL_F
; /* not `ureal' */
2361 tmp
= SCM_REALPART (second
);
2363 return SCM_BOOL_F
; /* not `ureal' */
2364 return scm_makdbl (res
, (lead_sgn
* tmp
));
2366 #endif /* SCM_FLOATS */
2371 scm_istring2number (str
, len
, radix
)
2378 char ex_p
= 0, rx_p
= 0; /* Only allow 1 exactness and 1 radix prefix */
2381 if (*str
== '+' || *str
== '-') /* Catches lone `+' and `-' for speed */
2384 while ((len
- i
) >= 2 && str
[i
] == '#' && ++i
)
2430 return scm_istr2int (&str
[i
], len
- i
, radix
);
2432 res
= scm_istr2int (&str
[i
], len
- i
, radix
);
2433 if (SCM_NFALSEP (res
))
2437 return scm_istr2flo (&str
[i
], len
- i
, radix
);
2444 SCM_PROC (s_string_to_number
, "string->number", 1, 1, 0, scm_string_to_number
);
2447 scm_string_to_number (str
, radix
)
2452 if (SCM_UNBNDP (radix
))
2453 radix
= SCM_MAKINUM (10L);
2455 SCM_ASSERT (SCM_INUMP (radix
), radix
, SCM_ARG2
, s_string_to_number
);
2456 SCM_ASSERT (SCM_NIMP (str
) && SCM_ROSTRINGP (str
),
2457 str
, SCM_ARG1
, s_string_to_number
);
2458 answer
= scm_istring2number (SCM_ROCHARS (str
),
2461 return scm_return_first (answer
, str
);
2463 /*** END strs->nums ***/
2473 if ((y
== 0.0) && (x
== 0.0))
2480 #ifndef SCM_SINGLESONLY
2481 if ((-FLTMAX
< x
) && (x
< FLTMAX
) && (fx
== x
))
2484 SCM_NEWSMOB(z
,scm_tc_flo
,NULL
);
2489 #endif /* def SCM_SINGLES */
2490 SCM_NEWSMOB(z
,scm_tc_dblr
,scm_must_malloc (1L * sizeof (double), "real"));
2494 SCM_NEWSMOB(z
,scm_tc_dblc
,scm_must_malloc (2L * sizeof (double), "comkplex"));
2511 if (0 == scm_bigcomp (x
, y
))
2525 if (SCM_REALPART (x
) != SCM_REALPART (y
))
2527 if (!(SCM_CPLXP (x
) && (SCM_IMAG (x
) != SCM_IMAG (y
))))
2536 SCM_PROC (s_number_p
, "number?", 1, 0, 0, scm_number_p
);
2537 SCM_PROC (s_complex_p
, "complex?", 1, 0, 0, scm_number_p
);
2546 if (SCM_NIMP (x
) && SCM_NUMP (x
))
2550 if (SCM_NIMP (x
) && SCM_NUMP (x
))
2560 SCM_PROC (s_real_p
, "real?", 1, 0, 0, scm_real_p
);
2561 SCM_PROC (s_rational_p
, "rational?", 1, 0, 0, scm_real_p
);
2582 SCM_PROC (s_int_p
, "integer?", 1, 0, 0, scm_integer_p
);
2601 r
= SCM_REALPART (x
);
2609 #endif /* SCM_FLOATS */
2611 SCM_PROC (s_inexact_p
, "inexact?", 1, 0, 0, scm_inexact_p
);
2618 if (SCM_NIMP (x
) && SCM_INEXP (x
))
2627 SCM_GPROC1 (s_eq_p
, "=", scm_tc7_rpsubr
, scm_num_eq_p
, g_eq_p
);
2639 #ifndef SCM_RECKLESS
2640 if (!(SCM_NIMP (x
)))
2643 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2650 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2652 return (0 == scm_bigcomp (x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2653 SCM_ASRTGO (SCM_INEXP (y
), bady
);
2655 return ((SCM_REALP (y
) && (scm_big2dbl (x
) == SCM_REALPART (y
)))
2659 SCM_ASRTGO (SCM_INEXP (x
), badx
);
2661 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_INEXP (x
),
2662 g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2672 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2680 SCM_ASRTGO (SCM_INEXP (y
), bady
);
2682 SCM_ASRTGO (SCM_NIMP (y
) && SCM_INEXP (y
), bady
);
2684 if (SCM_REALPART (x
) != SCM_REALPART (y
))
2687 return ((SCM_CPLXP (y
) && (SCM_IMAG (x
) == SCM_IMAG (y
)))
2690 return SCM_CPLXP (y
) ? SCM_BOOL_F
: SCM_BOOL_T
;
2695 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2698 #ifndef SCM_RECKLESS
2699 if (!(SCM_INEXP (y
)))
2702 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2706 #ifndef SCM_RECKLESS
2707 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
2710 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2715 return ((SCM_REALP (y
) && (((double) SCM_INUM (x
)) == SCM_REALPART (y
)))
2723 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
2724 g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2727 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
2728 return (0 == scm_bigcomp (x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2732 #ifndef SCM_RECKLESS
2733 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
2736 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2742 SCM_GASSERT2 (SCM_INUMP (x
), g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2743 SCM_GASSERT2 (SCM_INUMP (y
), g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2746 return ((long) x
== (long) y
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2751 SCM_GPROC1 (s_less_p
, "<", scm_tc7_rpsubr
, scm_less_p
, g_less_p
);
2762 #ifndef SCM_RECKLESS
2763 if (!(SCM_NIMP (x
)))
2766 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2772 return SCM_BIGSIGN (x
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2773 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2775 return (1 == scm_bigcomp (x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2776 SCM_ASRTGO (SCM_REALP (y
), bady
);
2777 return ((scm_big2dbl (x
) < SCM_REALPART (y
))
2781 SCM_ASRTGO (SCM_REALP (x
), badx
);
2783 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_REALP (x
),
2784 g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2787 return ((SCM_REALPART (x
) < ((double) SCM_INUM (y
)))
2791 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2793 return (SCM_REALPART (x
) < scm_big2dbl (y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2794 SCM_ASRTGO (SCM_REALP (y
), bady
);
2796 SCM_ASRTGO (SCM_NIMP (y
) && SCM_REALP (y
), bady
);
2798 return (SCM_REALPART (x
) < SCM_REALPART (y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2803 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2805 return SCM_BIGSIGN (y
) ? SCM_BOOL_F
: SCM_BOOL_T
;
2806 #ifndef SCM_RECKLESS
2807 if (!(SCM_REALP (y
)))
2810 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2814 #ifndef SCM_RECKLESS
2815 if (!(SCM_NIMP (y
) && SCM_REALP (y
)))
2818 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2822 return ((((double) SCM_INUM (x
)) < SCM_REALPART (y
))
2830 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
2831 g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2833 return SCM_BIGSIGN (x
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2834 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
2835 return (1 == scm_bigcomp (x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2839 #ifndef SCM_RECKLESS
2840 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
2843 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2846 return SCM_BIGSIGN (y
) ? SCM_BOOL_F
: SCM_BOOL_T
;
2849 SCM_GASSERT2 (SCM_INUMP (x
), g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2850 SCM_GASSERT2 (SCM_INUMP (y
), g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2853 return ((long) x
< (long) y
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2857 SCM_PROC1 (s_gr_p
, ">", scm_tc7_rpsubr
, scm_gr_p
);
2864 return scm_less_p (y
, x
);
2869 SCM_PROC1 (s_leq_p
, "<=", scm_tc7_rpsubr
, scm_leq_p
);
2876 return SCM_BOOL_NOT (scm_less_p (y
, x
));
2881 SCM_PROC1 (s_geq_p
, ">=", scm_tc7_rpsubr
, scm_geq_p
);
2888 return SCM_BOOL_NOT (scm_less_p (x
, y
));
2893 SCM_GPROC (s_zero_p
, "zero?", 1, 0, 0, scm_zero_p
, g_zero_p
);
2903 SCM_ASRTGO (SCM_NIMP (z
), badz
);
2906 #ifndef SCM_RECKLESS
2907 if (!(SCM_INEXP (z
)))
2910 SCM_WTA_DISPATCH_1 (g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2914 SCM_GASSERT1 (SCM_NIMP (z
) && SCM_INEXP (z
),
2915 g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2917 return (z
== scm_flo0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2923 SCM_GASSERT1 (SCM_NIMP (z
) && SCM_BIGP (z
),
2924 g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2928 SCM_GASSERT1 (SCM_INUMP (z
), g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2931 return (z
== SCM_INUM0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2936 SCM_GPROC (s_positive_p
, "positive?", 1, 0, 0, scm_positive_p
, g_positive_p
);
2946 SCM_ASRTGO (SCM_NIMP (x
), badx
);
2948 return SCM_TYP16 (x
) == scm_tc16_bigpos
? SCM_BOOL_T
: SCM_BOOL_F
;
2949 #ifndef SCM_RECKLESS
2950 if (!(SCM_REALP (x
)))
2953 SCM_WTA_DISPATCH_1 (g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2957 SCM_GASSERT1 (SCM_NIMP (x
) && SCM_REALP (x
),
2958 g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2960 return (SCM_REALPART (x
) > 0.0) ? SCM_BOOL_T
: SCM_BOOL_F
;
2966 SCM_GASSERT1 (SCM_NIMP (x
) && SCM_BIGP (x
),
2967 g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2968 return SCM_TYP16 (x
) == scm_tc16_bigpos
? SCM_BOOL_T
: SCM_BOOL_F
;
2971 SCM_GASSERT1 (SCM_INUMP (x
), g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2974 return (x
> SCM_INUM0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2979 SCM_GPROC (s_negative_p
, "negative?", 1, 0, 0, scm_negative_p
, g_negative_p
);
2989 SCM_ASRTGO (SCM_NIMP (x
), badx
);
2991 return SCM_TYP16 (x
) == scm_tc16_bigpos
? SCM_BOOL_F
: SCM_BOOL_T
;
2992 #ifndef SCM_RECKLESS
2993 if (!(SCM_REALP (x
)))
2996 SCM_WTA_DISPATCH_1 (g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
3000 SCM_GASSERT1 (SCM_NIMP (x
) && SCM_REALP (x
),
3001 g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
3003 return (SCM_REALPART (x
) < 0.0) ? SCM_BOOL_T
: SCM_BOOL_F
;
3009 SCM_GASSERT1 (SCM_NIMP (x
) && SCM_BIGP (x
),
3010 g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
3011 return (SCM_TYP16 (x
) == scm_tc16_bigneg
) ? SCM_BOOL_T
: SCM_BOOL_F
;
3014 SCM_GASSERT1 (SCM_INUMP (x
), g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
3017 return (x
< SCM_INUM0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
3021 SCM_GPROC1 (s_max
, "max", scm_tc7_asubr
, scm_max
, g_max
);
3033 SCM_GASSERT0 (!SCM_UNBNDP (x
),
3034 g_max
, scm_makfrom0str (s_max
), SCM_WNA
, 0);
3035 SCM_GASSERT1 (SCM_NUMBERP (x
), g_max
, x
, SCM_ARG1
, s_max
);
3045 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARG1
, s_max
);
3050 return SCM_BIGSIGN (x
) ? y
: x
;
3051 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3053 return (1 == scm_bigcomp (x
, y
)) ? y
: x
;
3054 SCM_ASRTGO (SCM_REALP (y
), bady
);
3055 z
= scm_big2dbl (x
);
3056 return (z
< SCM_REALPART (y
)) ? y
: scm_makdbl (z
, 0.0);
3058 SCM_ASRTGO (SCM_REALP (x
), badx2
);
3060 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_REALP (x
),
3061 g_max
, x
, y
, SCM_ARG1
, s_max
);
3064 return ((SCM_REALPART (x
) < (z
= SCM_INUM (y
)))
3065 ? scm_makdbl (z
, 0.0)
3068 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3070 return ((SCM_REALPART (x
) < (z
= scm_big2dbl (y
)))
3071 ? scm_makdbl (z
, 0.0)
3073 SCM_ASRTGO (SCM_REALP (y
), bady
);
3075 SCM_ASRTGO (SCM_NIMP (y
) && SCM_REALP (y
), bady
);
3077 return (SCM_REALPART (x
) < SCM_REALPART (y
)) ? y
: x
;
3082 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3084 return SCM_BIGSIGN (y
) ? x
: y
;
3085 #ifndef SCM_RECKLESS
3086 if (!(SCM_REALP (y
)))
3089 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARGn
, s_max
);
3093 #ifndef SCM_RECKLESS
3094 if (!(SCM_NIMP (y
) && SCM_REALP (y
)))
3097 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARGn
, s_max
);
3101 return (((z
= SCM_INUM (x
)) < SCM_REALPART (y
))
3103 : scm_makdbl (z
, 0.0));
3109 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
3110 g_max
, x
, y
, SCM_ARG1
, s_max
);
3112 return SCM_BIGSIGN (x
) ? y
: x
;
3113 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3114 return (1 == scm_bigcomp (x
, y
)) ? y
: x
;
3118 #ifndef SCM_RECKLESS
3119 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3122 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARGn
, s_max
);
3125 return SCM_BIGSIGN (y
) ? x
: y
;
3128 SCM_GASSERT2 (SCM_INUMP (x
), g_max
, x
, y
, SCM_ARG1
, s_max
);
3129 SCM_GASSERT2 (SCM_INUMP (y
), g_max
, x
, y
, SCM_ARGn
, s_max
);
3132 return ((long) x
< (long) y
) ? y
: x
;
3138 SCM_GPROC1 (s_min
, "min", scm_tc7_asubr
, scm_min
, g_min
);
3150 SCM_GASSERT0 (!SCM_UNBNDP (x
),
3151 g_min
, scm_makfrom0str (s_min
), SCM_WNA
, 0);
3152 SCM_GASSERT1 (SCM_NUMBERP (x
), g_min
, x
, SCM_ARG1
, s_min
);
3159 if (!(SCM_NIMP (x
)))
3162 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARG1
, s_min
);
3167 return SCM_BIGSIGN (x
) ? x
: y
;
3168 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3170 return (-1 == scm_bigcomp (x
, y
)) ? y
: x
;
3171 SCM_ASRTGO (SCM_REALP (y
), bady
);
3172 z
= scm_big2dbl (x
);
3173 return (z
> SCM_REALPART (y
)) ? y
: scm_makdbl (z
, 0.0);
3175 SCM_ASRTGO (SCM_REALP (x
), badx2
);
3177 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_REALP (x
),
3178 g_min
, x
, y
, SCM_ARG1
, s_min
);
3181 return ((SCM_REALPART (x
) > (z
= SCM_INUM (y
)))
3182 ? scm_makdbl (z
, 0.0)
3185 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3187 return ((SCM_REALPART (x
) > (z
= scm_big2dbl (y
)))
3188 ? scm_makdbl (z
, 0.0)
3190 SCM_ASRTGO (SCM_REALP (y
), bady
);
3192 SCM_ASRTGO (SCM_NIMP (y
) && SCM_REALP (y
), bady
);
3194 return (SCM_REALPART (x
) > SCM_REALPART (y
)) ? y
: x
;
3199 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3201 return SCM_BIGSIGN (y
) ? y
: x
;
3202 #ifndef SCM_RECKLESS
3203 if (!(SCM_REALP (y
)))
3206 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARGn
, s_min
);
3210 #ifndef SCM_RECKLESS
3211 if (!(SCM_NIMP (y
) && SCM_REALP (y
)))
3214 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARGn
, s_min
);
3218 return (((z
= SCM_INUM (x
)) > SCM_REALPART (y
))
3220 : scm_makdbl (z
, 0.0));
3226 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
3227 g_min
, x
, y
, SCM_ARG1
, s_min
);
3229 return SCM_BIGSIGN (x
) ? x
: y
;
3230 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3231 return (-1 == scm_bigcomp (x
, y
)) ? y
: x
;
3235 #ifndef SCM_RECKLESS
3236 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3239 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARGn
, s_min
);
3242 return SCM_BIGSIGN (y
) ? y
: x
;
3245 SCM_GASSERT2 (SCM_INUMP (x
), g_min
, x
, y
, SCM_ARG1
, s_min
);
3246 SCM_GASSERT2 (SCM_INUMP (y
), g_min
, x
, y
, SCM_ARGn
, s_min
);
3249 return ((long) x
> (long) y
) ? y
: x
;
3255 SCM_GPROC1 (s_sum
, "+", scm_tc7_asubr
, scm_sum
, g_sum
);
3266 #ifndef SCM_RECKLESS
3267 SCM_GASSERT1 (SCM_NUMBERP (x
), g_sum
, x
, SCM_ARG1
, s_sum
);
3279 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARG1
, s_sum
);
3290 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3293 if (SCM_NUMDIGS (x
) > SCM_NUMDIGS (y
))
3299 return scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3303 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3305 return scm_makdbl (scm_big2dbl (x
) + SCM_REALPART (y
),
3306 SCM_CPLXP (y
) ? SCM_IMAG (y
) : 0.0);
3308 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3310 SCM_ASRTGO (SCM_NIMP (x
) && SCM_INEXP (x
), badx2
);
3320 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3328 #ifndef SCM_RECKLESS
3329 else if (!(SCM_INEXP (y
)))
3332 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3336 #ifndef SCM_RECKLESS
3337 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
3340 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3350 return scm_makdbl (SCM_REALPART (x
) + SCM_REALPART (y
), i
);
3356 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3361 #ifndef SCM_DIGSTOOBIG
3362 long z
= scm_pseudolong (SCM_INUM (x
));
3363 return scm_addbig ((SCM_BIGDIG
*) & z
,
3365 (x
< 0) ? 0x0100 : 0,
3368 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3369 scm_longdigs (SCM_INUM (x
), zdigs
);
3370 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3375 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3377 SCM_ASRTGO (SCM_NIMP (y
) && SCM_INEXP (y
), bady
);
3380 return scm_makdbl (SCM_INUM (x
) + SCM_REALPART (y
),
3381 SCM_CPLXP (y
) ? SCM_IMAG (y
) : 0.0);
3388 SCM_ASRTGO (SCM_NIMP (x
) && SCM_BIGP (x
), badx2
);
3396 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3397 if (SCM_NUMDIGS (x
) > SCM_NUMDIGS (y
))
3403 return scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
), SCM_BIGSIGN (x
),
3408 #ifndef SCM_RECKLESS
3409 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3412 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3417 #ifndef SCM_DIGSTOOBIG
3418 long z
= scm_pseudolong (SCM_INUM (x
));
3419 return scm_addbig (&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
3421 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3422 scm_longdigs (SCM_INUM (x
), zdigs
);
3423 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
3428 SCM_ASRTGO (SCM_INUMP (x
), badx2
);
3429 SCM_GASSERT2 (SCM_INUMP (y
), g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3432 x
= SCM_INUM (x
) + SCM_INUM (y
);
3433 if (SCM_FIXABLE (x
))
3434 return SCM_MAKINUM (x
);
3436 return scm_long2big (x
);
3439 return scm_makdbl ((double) x
, 0.0);
3441 scm_num_overflow (s_sum
);
3442 return SCM_UNSPECIFIED
;
3450 SCM_GPROC1 (s_difference
, "-", scm_tc7_asubr
, scm_difference
, g_difference
);
3453 scm_difference (x
, y
)
3460 #ifndef SCM_RECKLESS
3461 if (!(SCM_NIMP (x
)))
3465 SCM_GASSERT0 (!SCM_UNBNDP (x
), g_difference
,
3466 scm_makfrom0str (s_difference
), SCM_WNA
, 0);
3468 SCM_WTA_DISPATCH_1 (g_difference
, x
, SCM_ARG1
, s_difference
);
3473 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARG1
, s_difference
);
3482 x
= scm_copybig (x
, !SCM_BIGSIGN (x
));
3483 return (SCM_NUMDIGS (x
) * SCM_BITSPERDIG
/ SCM_CHAR_BIT
3485 ? scm_big2inum (x
, SCM_NUMDIGS (x
))
3489 SCM_ASRTGO (SCM_INEXP (x
), badx
);
3490 return scm_makdbl (- SCM_REALPART (x
),
3491 SCM_CPLXP (x
) ? -SCM_IMAG (x
) : 0.0);
3494 return scm_sum (x
, SCM_MAKINUM (- SCM_INUM (y
)));
3496 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3500 return ((SCM_NUMDIGS (x
) < SCM_NUMDIGS (y
))
3501 ? scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3504 : scm_addbig (SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3505 SCM_BIGSIGN (y
) ^ 0x0100,
3507 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3508 return scm_makdbl (scm_big2dbl (x
) - SCM_REALPART (y
),
3509 SCM_CPLXP (y
) ? -SCM_IMAG (y
) : 0.0);
3511 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3513 return scm_makdbl (SCM_REALPART (x
) - scm_big2dbl (y
),
3514 SCM_CPLXP (x
) ? SCM_IMAG (x
) : 0.0);
3515 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3517 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3518 SCM_ASRTGO (SCM_NIMP (y
) && SCM_INEXP (y
), bady
);
3523 return scm_makdbl (SCM_REAL (x
) - SCM_REAL (y
),
3524 SCM_IMAG (x
) - SCM_IMAG (y
));
3526 return scm_makdbl (SCM_REAL (x
) - SCM_REALPART (y
), SCM_IMAG (x
));
3528 return scm_makdbl (SCM_REALPART (x
) - SCM_REALPART (y
),
3529 SCM_CPLXP (y
) ? - SCM_IMAG (y
) : 0.0);
3539 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3542 #ifndef SCM_DIGSTOOBIG
3543 long z
= scm_pseudolong (SCM_INUM (x
));
3544 return scm_addbig ((SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3545 (x
< 0) ? 0x0100 : 0,
3548 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3549 scm_longdigs (SCM_INUM (x
), zdigs
);
3550 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3554 #ifndef SCM_RECKLESS
3555 if (!(SCM_INEXP (y
)))
3558 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3562 #ifndef SCM_RECKLESS
3563 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
3566 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3570 return scm_makdbl (SCM_INUM (x
) - SCM_REALPART (y
),
3571 SCM_CPLXP (y
) ? -SCM_IMAG (y
) : 0.0);
3577 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
3578 g_difference
, x
, y
, SCM_ARG1
, s_difference
);
3581 x
= scm_copybig (x
, !SCM_BIGSIGN (x
));
3582 return (SCM_NUMDIGS (x
) * SCM_BITSPERDIG
/ SCM_CHAR_BIT
3584 ? scm_big2inum (x
, SCM_NUMDIGS (x
))
3589 #ifndef SCM_DIGSTOOBIG
3590 long z
= scm_pseudolong (SCM_INUM (y
));
3591 return scm_addbig (&z
, SCM_DIGSPERLONG
, (y
< 0) ? 0 : 0x0100, x
, 0);
3593 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3594 scm_longdigs (SCM_INUM (x
), zdigs
);
3595 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (y
< 0) ? 0 : 0x0100,
3599 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3600 return (SCM_NUMDIGS (x
) < SCM_NUMDIGS (y
)) ?
3601 scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
), SCM_BIGSIGN (x
),
3603 scm_addbig (SCM_BDIGITS (y
), SCM_NUMDIGS (y
), SCM_BIGSIGN (y
) ^ 0x0100,
3613 #ifndef SCM_RECKLESS
3614 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3617 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3621 #ifndef SCM_DIGSTOOBIG
3622 long z
= scm_pseudolong (SCM_INUM (x
));
3623 return scm_addbig (&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3626 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3627 scm_longdigs (SCM_INUM (x
), zdigs
);
3628 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3634 SCM_GASSERT2 (SCM_INUMP (x
), g_difference
, x
, y
, SCM_ARG1
, s_difference
);
3640 SCM_GASSERT2 (SCM_INUMP (y
), g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3643 x
= SCM_INUM (x
) - SCM_INUM (y
);
3645 if (SCM_FIXABLE (x
))
3646 return SCM_MAKINUM (x
);
3648 return scm_long2big (x
);
3651 return scm_makdbl ((double) x
, 0.0);
3653 scm_num_overflow (s_difference
);
3654 return SCM_UNSPECIFIED
;
3662 SCM_GPROC1 (s_product
, "*", scm_tc7_asubr
, scm_product
, g_product
);
3672 return SCM_MAKINUM (1L);
3673 #ifndef SCM_RECKLESS
3674 SCM_GASSERT1 (SCM_NUMBERP (x
), g_product
, x
, SCM_ARG1
, s_product
);
3686 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARG1
, s_product
);
3697 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3699 return scm_mulbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3700 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3701 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
));
3702 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3705 double bg
= scm_big2dbl (x
);
3706 return scm_makdbl (bg
* SCM_REALPART (y
),
3707 SCM_CPLXP (y
) ? bg
* SCM_IMAG (y
) : 0.0);
3710 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3712 SCM_ASRTGO (SCM_NIMP (x
) && SCM_INEXP (x
), badx2
);
3722 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3730 #ifndef SCM_RECKLESS
3731 else if (!(SCM_INEXP (y
)))
3734 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARGn
, s_product
);
3738 #ifndef SCM_RECKLESS
3739 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
3742 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARGn
, s_product
);
3749 return scm_makdbl (SCM_REAL (x
) * SCM_REAL (y
)
3750 - SCM_IMAG (x
) * SCM_IMAG (y
),
3751 SCM_REAL (x
) * SCM_IMAG (y
)
3752 + SCM_IMAG (x
) * SCM_REAL (y
));
3754 return scm_makdbl (SCM_REAL (x
) * SCM_REALPART (y
),
3755 SCM_IMAG (x
) * SCM_REALPART (y
));
3757 return scm_makdbl (SCM_REALPART (x
) * SCM_REALPART (y
),
3759 ? SCM_REALPART (x
) * SCM_IMAG (y
)
3765 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3771 if (SCM_MAKINUM (1L) == x
)
3774 #ifndef SCM_DIGSTOOBIG
3775 long z
= scm_pseudolong (SCM_INUM (x
));
3776 return scm_mulbig ((SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3777 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3778 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3780 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3781 scm_longdigs (SCM_INUM (x
), zdigs
);
3782 return scm_mulbig (zdigs
, SCM_DIGSPERLONG
,
3783 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3784 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3788 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3790 SCM_ASRTGO (SCM_NIMP (y
) && SCM_INEXP (y
), bady
);
3793 return scm_makdbl (SCM_INUM (x
) * SCM_REALPART (y
),
3794 SCM_CPLXP (y
) ? SCM_INUM (x
) * SCM_IMAG (y
) : 0.0);
3800 SCM_ASRTGO (SCM_NIMP (x
) && SCM_BIGP (x
), badx2
);
3808 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3809 return scm_mulbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3810 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3811 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
));
3815 #ifndef SCM_RECKLESS
3816 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3819 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARGn
, s_product
);
3825 if (SCM_MAKINUM (1L) == x
)
3828 #ifndef SCM_DIGSTOOBIG
3829 long z
= scm_pseudolong (SCM_INUM (x
));
3830 return scm_mulbig (&z
, SCM_DIGSPERLONG
,
3831 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3832 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3834 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3835 scm_longdigs (SCM_INUM (x
), zdigs
);
3836 return scm_mulbig (zdigs
, SCM_DIGSPERLONG
,
3837 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3838 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3843 SCM_ASRTGO (SCM_INUMP (x
), badx2
);
3844 SCM_GASSERT (SCM_INUMP (y
), g_product
, x
, y
, SCM_ARGn
, s_product
);
3854 y
= SCM_MAKINUM (k
);
3855 if (k
!= SCM_INUM (y
) || k
/ i
!= j
)
3858 int sgn
= (i
< 0) ^ (j
< 0);
3859 #ifndef SCM_DIGSTOOBIG
3860 i
= scm_pseudolong (i
);
3861 j
= scm_pseudolong (j
);
3862 return scm_mulbig ((SCM_BIGDIG
*) & i
, SCM_DIGSPERLONG
,
3863 (SCM_BIGDIG
*) & j
, SCM_DIGSPERLONG
, sgn
);
3864 #else /* SCM_DIGSTOOBIG */
3865 SCM_BIGDIG idigs
[SCM_DIGSPERLONG
];
3866 SCM_BIGDIG jdigs
[SCM_DIGSPERLONG
];
3867 scm_longdigs (i
, idigs
);
3868 scm_longdigs (j
, jdigs
);
3869 return scm_mulbig (idigs
, SCM_DIGSPERLONG
,
3870 jdigs
, SCM_DIGSPERLONG
,
3876 return scm_makdbl (((double) i
) * ((double) j
), 0.0);
3878 scm_num_overflow (s_product
);
3888 scm_num2dbl (a
, why
)
3893 return (double) SCM_INUM (a
);
3895 SCM_ASSERT (SCM_NIMP (a
), a
, "wrong type argument", why
);
3897 return (SCM_REALPART (a
));
3900 return scm_big2dbl (a
);
3902 SCM_ASSERT (0, a
, "wrong type argument", why
);
3903 return SCM_UNSPECIFIED
;
3907 SCM_GPROC1 (s_divide
, "/", scm_tc7_asubr
, scm_divide
, g_divide
);
3918 #ifndef SCM_RECKLESS
3919 if (!(SCM_NIMP (x
)))
3923 SCM_GASSERT0 (!SCM_UNBNDP (x
),
3924 g_divide
, scm_makfrom0str (s_divide
), SCM_WNA
, 0);
3926 SCM_WTA_DISPATCH_1 (g_divide
, x
, SCM_ARG1
, s_divide
);
3931 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARG1
, s_divide
);
3939 return scm_makdbl (1.0 / scm_big2dbl (x
), 0.0);
3941 SCM_ASRTGO (SCM_INEXP (x
), badx
);
3943 return scm_makdbl (1.0 / SCM_REALPART (x
), 0.0);
3947 return scm_makdbl (r
/ d
, -i
/ d
);
3956 #ifndef SCM_RECKLESS
3958 scm_num_overflow (s_divide
);
3966 SCM w
= scm_copybig (x
, SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0));
3967 return (scm_divbigdig (SCM_BDIGITS (w
), SCM_NUMDIGS (w
),
3969 ? scm_makdbl (scm_big2dbl (x
) / SCM_INUM (y
), 0.0)
3972 #ifndef SCM_DIGSTOOBIG
3973 z
= scm_pseudolong (z
);
3974 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3975 (SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3976 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
3979 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3980 scm_longdigs (z
, zdigs
);
3981 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3982 zdigs
, SCM_DIGSPERLONG
,
3983 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
3986 return z
? z
: scm_makdbl (scm_big2dbl (x
) / SCM_INUM (y
), 0.0);
3988 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3991 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3992 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3993 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
), 3);
3994 return z
? z
: scm_makdbl (scm_big2dbl (x
) / scm_big2dbl (y
),
3997 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3999 return scm_makdbl (scm_big2dbl (x
) / SCM_REALPART (y
), 0.0);
4000 a
= scm_big2dbl (x
);
4004 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
4011 SCM_ASRTGO (SCM_NIMP (y
), bady
);
4014 d
= scm_big2dbl (y
);
4017 SCM_ASRTGO (SCM_INEXP (y
), bady
);
4019 SCM_ASRTGO (SCM_NIMP (y
) && SCM_INEXP (y
), bady
);
4023 d
= SCM_REALPART (y
);
4025 return scm_makdbl (SCM_REALPART (x
) / d
,
4026 SCM_CPLXP (x
) ? SCM_IMAG (x
) / d
: 0.0);
4028 a
= SCM_REALPART (x
);
4034 return scm_makdbl ((a
* r
+ SCM_IMAG (x
) * i
) / d
,
4035 (SCM_IMAG (x
) * r
- a
* i
) / d
);
4039 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
4041 return scm_makdbl (1.0 / ((double) SCM_INUM (x
)), 0.0);
4046 SCM_ASRTGO (SCM_NIMP (y
), bady
);
4048 return scm_makdbl (SCM_INUM (x
) / scm_big2dbl (y
), 0.0);
4049 #ifndef SCM_RECKLESS
4050 if (!(SCM_INEXP (y
)))
4053 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARGn
, s_divide
);
4057 #ifndef SCM_RECKLESS
4058 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
4061 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARGn
, s_divide
);
4066 return scm_makdbl (SCM_INUM (x
) / SCM_REALPART (y
), 0.0);
4072 return scm_makdbl ((a
* r
) / d
, (-a
* i
) / d
);
4079 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
4080 g_divide
, x
, y
, SCM_ARG1
, s_divide
);
4094 SCM w
= scm_copybig (x
, SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0));
4095 if (scm_divbigdig (SCM_BDIGITS (w
), SCM_NUMDIGS (w
),
4100 #ifndef SCM_DIGSTOOBIG
4101 z
= scm_pseudolong (z
);
4102 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
4103 &z
, SCM_DIGSPERLONG
,
4104 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
4107 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
4108 scm_longdigs (z
, zdigs
);
4109 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
4110 zdigs
, SCM_DIGSPERLONG
,
4111 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
4117 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
4118 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
4119 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
4120 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
), 3);
4128 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
4134 #ifndef SCM_RECKLESS
4135 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
4138 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARGn
, s_divide
);
4144 SCM_GASSERT2 (SCM_INUMP (x
), g_divide
, x
, y
, SCM_ARG1
, s_divide
);
4147 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
4151 SCM_GASSERT2 (SCM_INUMP (y
), g_divide
, x
, y
, SCM_ARGn
, s_divide
);
4155 long z
= SCM_INUM (y
);
4156 if ((0 == z
) || SCM_INUM (x
) % z
)
4158 z
= SCM_INUM (x
) / z
;
4159 if (SCM_FIXABLE (z
))
4160 return SCM_MAKINUM (z
);
4162 return scm_long2big (z
);
4166 return scm_makdbl (((double) SCM_INUM (x
)) / ((double) SCM_INUM (y
)), 0.0);
4169 scm_num_overflow (s_divide
);
4170 return SCM_UNSPECIFIED
;
4179 SCM_GPROC1 (s_asinh
, "$asinh", scm_tc7_cxr
, (SCM (*)()) scm_asinh
, g_asinh
);
4185 return log (x
+ sqrt (x
* x
+ 1));
4191 SCM_GPROC1 (s_acosh
, "$acosh", scm_tc7_cxr
, (SCM (*)()) scm_acosh
, g_acosh
);
4197 return log (x
+ sqrt (x
* x
- 1));
4203 SCM_GPROC1 (s_atanh
, "$atanh", scm_tc7_cxr
, (SCM (*)()) scm_atanh
, g_atanh
);
4209 return 0.5 * log ((1 + x
) / (1 - x
));
4215 SCM_GPROC1 (s_truncate
, "truncate", scm_tc7_cxr
, (SCM (*)()) scm_truncate
, g_truncate
);
4228 SCM_GPROC1 (s_round
, "round", scm_tc7_cxr
, (SCM (*)()) scm_round
, g_round
);
4234 double plus_half
= x
+ 0.5;
4235 double result
= floor (plus_half
);
4236 /* Adjust so that the scm_round is towards even. */
4237 return (plus_half
== result
&& plus_half
/ 2 != floor (plus_half
/ 2))
4238 ? result
- 1 : result
;
4243 SCM_GPROC1 (s_exact_to_inexact
, "exact->inexact", scm_tc7_cxr
, (SCM (*)()) scm_exact_to_inexact
, g_exact_to_inexact
);
4246 scm_exact_to_inexact (z
)
4253 SCM_GPROC1 (s_i_floor
, "floor", scm_tc7_cxr
, (SCM (*)()) floor
, g_i_floor
);
4254 SCM_GPROC1 (s_i_ceil
, "ceiling", scm_tc7_cxr
, (SCM (*)()) ceil
, g_i_ceil
);
4255 SCM_GPROC1 (s_i_sqrt
, "$sqrt", scm_tc7_cxr
, (SCM (*)()) sqrt
, g_i_sqrt
);
4256 SCM_GPROC1 (s_i_abs
, "$abs", scm_tc7_cxr
, (SCM (*)()) fabs
, g_i_abs
);
4257 SCM_GPROC1 (s_i_exp
, "$exp", scm_tc7_cxr
, (SCM (*)()) exp
, g_i_exp
);
4258 SCM_GPROC1 (s_i_log
, "$log", scm_tc7_cxr
, (SCM (*)()) log
, g_i_log
);
4259 SCM_GPROC1 (s_i_sin
, "$sin", scm_tc7_cxr
, (SCM (*)()) sin
, g_i_sin
);
4260 SCM_GPROC1 (s_i_cos
, "$cos", scm_tc7_cxr
, (SCM (*)()) cos
, g_i_cos
);
4261 SCM_GPROC1 (s_i_tan
, "$tan", scm_tc7_cxr
, (SCM (*)()) tan
, g_i_tan
);
4262 SCM_GPROC1 (s_i_asin
, "$asin", scm_tc7_cxr
, (SCM (*)()) asin
, g_i_asin
);
4263 SCM_GPROC1 (s_i_acos
, "$acos", scm_tc7_cxr
, (SCM (*)()) acos
, g_i_acos
);
4264 SCM_GPROC1 (s_i_atan
, "$atan", scm_tc7_cxr
, (SCM (*)()) atan
, g_i_atan
);
4265 SCM_GPROC1 (s_i_sinh
, "$sinh", scm_tc7_cxr
, (SCM (*)()) sinh
, g_i_sinh
);
4266 SCM_GPROC1 (s_i_cosh
, "$cosh", scm_tc7_cxr
, (SCM (*)()) cosh
, g_i_cosh
);
4267 SCM_GPROC1 (s_i_tanh
, "$tanh", scm_tc7_cxr
, (SCM (*)()) tanh
, g_i_tanh
);
4274 static void scm_two_doubles (SCM z1
,
4276 const char *sstring
,
4280 scm_two_doubles (z1
, z2
, sstring
, xy
)
4282 const char *sstring
;
4286 xy
->x
= SCM_INUM (z1
);
4290 SCM_ASRTGO (SCM_NIMP (z1
), badz1
);
4292 xy
->x
= scm_big2dbl (z1
);
4295 #ifndef SCM_RECKLESS
4296 if (!(SCM_REALP (z1
)))
4297 badz1
:scm_wta (z1
, (char *) SCM_ARG1
, sstring
);
4299 xy
->x
= SCM_REALPART (z1
);
4303 SCM_ASSERT (SCM_NIMP (z1
) && SCM_REALP (z1
), z1
, SCM_ARG1
, sstring
);
4304 xy
->x
= SCM_REALPART (z1
);
4309 xy
->y
= SCM_INUM (z2
);
4313 SCM_ASRTGO (SCM_NIMP (z2
), badz2
);
4315 xy
->y
= scm_big2dbl (z2
);
4318 #ifndef SCM_RECKLESS
4319 if (!(SCM_REALP (z2
)))
4320 badz2
:scm_wta (z2
, (char *) SCM_ARG2
, sstring
);
4322 xy
->y
= SCM_REALPART (z2
);
4326 SCM_ASSERT (SCM_NIMP (z2
) && SCM_REALP (z2
), z2
, SCM_ARG2
, sstring
);
4327 xy
->y
= SCM_REALPART (z2
);
4336 SCM_PROC (s_sys_expt
, "$expt", 2, 0, 0, scm_sys_expt
);
4339 scm_sys_expt (z1
, z2
)
4344 scm_two_doubles (z1
, z2
, s_sys_expt
, &xy
);
4345 return scm_makdbl (pow (xy
.x
, xy
.y
), 0.0);
4350 SCM_PROC (s_sys_atan2
, "$atan2", 2, 0, 0, scm_sys_atan2
);
4353 scm_sys_atan2 (z1
, z2
)
4358 scm_two_doubles (z1
, z2
, s_sys_atan2
, &xy
);
4359 return scm_makdbl (atan2 (xy
.x
, xy
.y
), 0.0);
4364 SCM_PROC (s_make_rectangular
, "make-rectangular", 2, 0, 0, scm_make_rectangular
);
4367 scm_make_rectangular (z1
, z2
)
4372 scm_two_doubles (z1
, z2
, s_make_rectangular
, &xy
);
4373 return scm_makdbl (xy
.x
, xy
.y
);
4378 SCM_PROC (s_make_polar
, "make-polar", 2, 0, 0, scm_make_polar
);
4381 scm_make_polar (z1
, z2
)
4386 scm_two_doubles (z1
, z2
, s_make_polar
, &xy
);
4387 return scm_makdbl (xy
.x
* cos (xy
.y
), xy
.x
* sin (xy
.y
));
4393 SCM_GPROC (s_real_part
, "real-part", 1, 0, 0, scm_real_part
, g_real_part
);
4402 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4405 #ifndef SCM_RECKLESS
4406 if (!(SCM_INEXP (z
)))
4409 SCM_WTA_DISPATCH_1 (g_real_part
, z
, SCM_ARG1
, s_real_part
);
4413 SCM_GASSERT1 (SCM_NIMP (z
) && SCM_INEXP (z
),
4414 g_real_part
, z
, SCM_ARG1
, s_real_part
);
4417 return scm_makdbl (SCM_REAL (z
), 0.0);
4424 SCM_GPROC (s_imag_part
, "imag-part", 1, 0, 0, scm_imag_part
, g_imag_part
);
4433 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4436 #ifndef SCM_RECKLESS
4437 if (!(SCM_INEXP (z
)))
4440 SCM_WTA_DISPATCH_1 (g_imag_part
, z
, SCM_ARG1
, s_imag_part
);
4444 SCM_GASSERT1 (SCM_NIMP (z
) && SCM_INEXP (z
),
4445 g_imag_part
, z
, SCM_ARG1
, s_imag_part
);
4448 return scm_makdbl (SCM_IMAG (z
), 0.0);
4454 SCM_GPROC (s_magnitude
, "magnitude", 1, 0, 0, scm_magnitude
, g_magnitude
);
4463 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4466 #ifndef SCM_RECKLESS
4467 if (!(SCM_INEXP (z
)))
4470 SCM_WTA_DISPATCH_1 (g_magnitude
, z
, SCM_ARG1
, s_magnitude
);
4474 SCM_GASSERT1 (SCM_NIMP (z
) && SCM_INEXP (z
),
4475 g_magnitude
, z
, SCM_ARG1
, s_magnitude
);
4479 double i
= SCM_IMAG (z
), r
= SCM_REAL (z
);
4480 return scm_makdbl (sqrt (i
* i
+ r
* r
), 0.0);
4482 return scm_makdbl (fabs (SCM_REALPART (z
)), 0.0);
4488 SCM_GPROC (s_angle
, "angle", 1, 0, 0, scm_angle
, g_angle
);
4497 x
= (z
>= SCM_INUM0
) ? 1.0 : -1.0;
4501 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4504 x
= (SCM_TYP16 (z
) == scm_tc16_bigpos
) ? 1.0 : -1.0;
4507 #ifndef SCM_RECKLESS
4508 if (!(SCM_INEXP (z
)))
4511 SCM_WTA_DISPATCH_1 (g_angle
, z
, SCM_ARG1
, s_angle
);
4515 SCM_GASSERT1 (SCM_NIMP (z
) && SCM_INEXP (z
), g_angle
, z
, SCM_ARG1
, s_angle
);
4519 x
= SCM_REALPART (z
);
4525 return scm_makdbl (atan2 (y
, x
), 0.0);
4529 SCM_PROC (s_inexact_to_exact
, "inexact->exact", 1, 0, 0, scm_inexact_to_exact
);
4532 scm_inexact_to_exact (z
)
4538 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4541 #ifndef SCM_RECKLESS
4542 if (!(SCM_REALP (z
)))
4545 scm_wta (z
, (char *) SCM_ARG1
, s_inexact_to_exact
);
4549 SCM_ASSERT (SCM_NIMP (z
) && SCM_REALP (z
), z
, SCM_ARG1
, s_inexact_to_exact
);
4553 double u
= floor (SCM_REALPART (z
) + 0.5);
4554 if ((u
<= SCM_MOST_POSITIVE_FIXNUM
) && (-u
<= -SCM_MOST_NEGATIVE_FIXNUM
))
4556 /* Negation is a workaround for HP700 cc bug */
4557 SCM ans
= SCM_MAKINUM ((long) u
);
4558 if (SCM_INUM (ans
) == (long) u
)
4561 SCM_ASRTGO (isfinite (u
), badz
); /* problem? */
4562 return scm_dbl2big (u
);
4565 return SCM_MAKINUM ((long) floor (SCM_REALPART (z
) + 0.5));
4571 #else /* ~SCM_FLOATS */
4572 SCM_GPROC (s_trunc
, "truncate", 1, 0, 0, scm_trunc
, g_trunc
);
4578 SCM_GASSERT2 (SCM_INUMP (x
), g_trunc
, x
, y
, SCM_ARG1
, s_truncate
);
4584 #endif /* SCM_FLOATS */
4588 /* d must be integer */
4598 double u
= (d
< 0) ? -d
: d
;
4599 while (0 != floor (u
))
4604 ans
= scm_mkbig (i
, d
< 0);
4605 digits
= SCM_BDIGITS (ans
);
4613 #ifndef SCM_RECKLESS
4615 scm_num_overflow ("dbl2big");
4627 scm_sizet i
= SCM_NUMDIGS (b
);
4628 SCM_BIGDIG
*digits
= SCM_BDIGITS (b
);
4630 ans
= digits
[i
] + SCM_BIGRAD
* ans
;
4631 if (scm_tc16_bigneg
== SCM_TYP16 (b
))
4643 if (!SCM_FIXABLE (sl
))
4646 return scm_long2big (sl
);
4649 return scm_makdbl ((double) sl
, 0.0);
4655 return SCM_MAKINUM (sl
);
4662 scm_long_long2num (sl
)
4665 if (!SCM_FIXABLE (sl
))
4668 return scm_long_long2big (sl
);
4671 return scm_makdbl ((double) sl
, 0.0);
4677 return SCM_MAKINUM (sl
);
4687 if (!SCM_POSFIXABLE (sl
))
4690 return scm_ulong2big (sl
);
4693 return scm_makdbl ((double) sl
, 0.0);
4699 return SCM_MAKINUM (sl
);
4704 scm_num2long (num
, pos
, s_caller
)
4707 const char *s_caller
;
4710 if (SCM_INUMP (num
))
4712 res
= SCM_INUM (num
);
4715 SCM_ASRTGO (SCM_NIMP (num
), errout
);
4717 if (SCM_REALP (num
))
4719 double u
= SCM_REALPART (num
);
4721 if ((double) res
== u
)
4734 for (l
= SCM_NUMDIGS (num
); l
--;)
4736 res
= SCM_BIGUP (res
) + SCM_BDIGITS (num
)[l
];
4741 if (SCM_TYP16 (num
) == scm_tc16_bigpos
)
4748 scm_wta (num
, pos
, s_caller
);
4749 return SCM_UNSPECIFIED
;
4757 scm_num2long_long (num
, pos
, s_caller
)
4760 const char *s_caller
;
4763 if (SCM_INUMP (num
))
4765 res
= SCM_INUM ((long_long
) num
);
4768 SCM_ASRTGO (SCM_NIMP (num
), errout
);
4770 if (SCM_REALP (num
))
4772 double u
= SCM_REALPART (num
);
4773 if (((SCM_MOST_NEGATIVE_FIXNUM
* 4) <= u
)
4774 && (u
<= (SCM_MOST_POSITIVE_FIXNUM
* 4 + 3)))
4784 scm_sizet l
= SCM_NUMDIGS (num
);
4785 SCM_ASRTGO (SCM_DIGSPERLONGLONG
>= l
, errout
);
4788 res
= SCM_LONGLONGBIGUP (res
) + SCM_BDIGITS (num
)[l
];
4793 scm_wta (num
, pos
, s_caller
);
4794 return SCM_UNSPECIFIED
;
4801 scm_num2ulong (num
, pos
, s_caller
)
4804 const char *s_caller
;
4807 if (SCM_INUMP (num
))
4809 res
= SCM_INUM ((unsigned long) num
);
4812 SCM_ASRTGO (SCM_NIMP (num
), errout
);
4814 if (SCM_REALP (num
))
4816 double u
= SCM_REALPART (num
);
4817 if ((0 <= u
) && (u
<= (unsigned long) ~0L))
4827 unsigned long oldres
;
4831 for (l
= SCM_NUMDIGS (num
); l
--;)
4833 res
= SCM_BIGUP (res
) + SCM_BDIGITS (num
)[l
];
4842 scm_wta (num
, pos
, s_caller
);
4843 return SCM_UNSPECIFIED
;
4849 static void add1
SCM_P ((double f
, double *fsum
));
4864 scm_add_feature("complex");
4866 scm_add_feature("inexact");
4868 SCM_NEWSMOB(scm_flo0
,scm_tc_flo
,NULL
);
4870 SCM_NEWSMOB(scm_flo0
,scm_tc_dblr
,scm_must_malloc (1L * sizeof (double), "real"));
4871 SCM_REAL (scm_flo0
) = 0.0;
4874 scm_dblprec
= (DBL_DIG
> 20) ? 20 : DBL_DIG
;
4876 { /* determine floating point precision */
4878 double fsum
= 1.0 + f
;
4882 if (++scm_dblprec
> 20)
4886 scm_dblprec
= scm_dblprec
- 1;
4888 #endif /* DBL_DIG */
4890 #include "numbers.x"