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);
223 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
226 SCM_WTA_DISPATCH_2 (g_quotient
, x
, y
, SCM_ARG2
, s_quotient
);
231 SCM_GASSERT2 (SCM_INUMP (x
), g_quotient
, x
, y
, SCM_ARG1
, s_quotient
);
232 SCM_GASSERT2 (SCM_INUMP (y
), g_quotient
, x
, y
, SCM_ARG2
, s_quotient
);
234 if ((z
= SCM_INUM (y
)) == 0)
237 scm_num_overflow (s_quotient
);
239 z
= SCM_INUM (x
) / z
;
242 #if (__TURBOC__ == 1)
243 long t
= ((y
< 0) ? -SCM_INUM (x
) : SCM_INUM (x
)) % SCM_INUM (y
);
245 long t
= SCM_INUM (x
) % SCM_INUM (y
);
256 if (!SCM_FIXABLE (z
))
258 return scm_long2big (z
);
260 scm_num_overflow (s_quotient
);
262 return SCM_MAKINUM (z
);
265 SCM_GPROC (s_remainder
, "remainder", 2, 0, 0, scm_remainder
, g_remainder
);
276 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
277 g_remainder
, x
, y
, SCM_ARG1
, s_remainder
);
280 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
281 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
282 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
285 if (!(z
= SCM_INUM (y
)))
287 return scm_divbigint (x
, z
, SCM_BIGSIGN (x
), 0);
291 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
294 SCM_WTA_DISPATCH_2 (g_remainder
, x
, y
, SCM_ARG2
, s_remainder
);
299 SCM_GASSERT2 (SCM_INUMP (x
), g_remainder
, x
, y
, SCM_ARG1
, s_remainder
);
300 SCM_GASSERT2 (SCM_INUMP (y
), g_remainder
, x
, y
, SCM_ARG2
, s_remainder
);
302 if (!(z
= SCM_INUM (y
)))
305 scm_num_overflow (s_remainder
);
307 #if (__TURBOC__ == 1)
311 z
= SCM_INUM (x
) % z
;
321 return SCM_MAKINUM (z
);
324 SCM_GPROC (s_modulo
, "modulo", 2, 0, 0, scm_modulo
, g_modulo
);
335 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
336 g_modulo
, x
, y
, SCM_ARG1
, s_modulo
);
339 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
340 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
341 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
343 (SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
)) ? 1 : 0);
345 if (!(z
= SCM_INUM (y
)))
347 return scm_divbigint (x
, z
, y
< 0,
348 (SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0)) ? 1 : 0);
352 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
355 SCM_WTA_DISPATCH_2 (g_modulo
, x
, y
, SCM_ARG2
, s_modulo
);
357 return (SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0)) ? scm_sum (x
, y
) : x
;
360 SCM_GASSERT1 (SCM_INUMP (x
), g_modulo
, x
, y
, SCM_ARG1
, s_modulo
);
361 SCM_GASSERT2 (SCM_INUMP (y
), g_modulo
, x
, y
, SCM_ARG2
, s_modulo
);
363 if (!(yy
= SCM_INUM (y
)))
366 scm_num_overflow (s_modulo
);
370 z
= ((yy
< 0) ? -z
: z
) % yy
;
372 z
= SCM_INUM (x
) % yy
;
374 return SCM_MAKINUM (((yy
< 0) ? (z
> 0) : (z
< 0)) ? z
+ yy
: z
);
377 SCM_GPROC1 (s_gcd
, "gcd", scm_tc7_asubr
, scm_gcd
, g_gcd
);
384 register long u
, v
, k
, t
;
386 return SCM_UNBNDP (x
) ? SCM_INUM0
: x
;
392 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
393 g_gcd
, x
, y
, SCM_ARG1
, s_gcd
);
395 x
= scm_copybig (x
, 0);
399 SCM_GASSERT2 (SCM_NIMP (y
) && SCM_BIGP (y
),
400 g_gcd
, x
, y
, SCM_ARGn
, s_gcd
);
402 y
= scm_copybig (y
, 0);
403 switch (scm_bigcomp (x
, y
))
407 t
= scm_remainder (x
, y
);
414 y
= scm_remainder (y
, x
);
417 /* instead of the switch, we could just
418 return scm_gcd (y, scm_modulo (x, y)); */
432 SCM_GASSERT2 (SCM_INUMP (x
), g_gcd
, x
, y
, SCM_ARG1
, s_gcd
);
433 SCM_GASSERT2 (SCM_INUMP (y
), g_gcd
, x
, y
, SCM_ARGn
, s_gcd
);
448 for (k
= 1; !(1 & ((int) u
| (int) v
)); k
<<= 1, u
>>= 1, v
>>= 1);
467 if (!SCM_POSFIXABLE (u
))
469 return scm_long2big (u
);
471 scm_num_overflow (s_gcd
);
473 return SCM_MAKINUM (u
);
476 SCM_GPROC1 (s_lcm
, "lcm", scm_tc7_asubr
, scm_lcm
, g_lcm
);
485 SCM_GASSERT2 (SCM_INUMP (n1
) || SCM_UNBNDP (n1
),
486 g_lcm
, n1
, n2
, SCM_ARG1
, s_lcm
);
487 SCM_GASSERT2 (SCM_INUMP (n2
) || SCM_UNBNDP (n2
),
488 g_lcm
, n1
, n2
, SCM_ARGn
, s_lcm
);
490 SCM_GASSERT2 (SCM_INUMP (n1
)
492 || (SCM_NIMP (n1
) && SCM_BIGP (n1
)),
493 g_lcm
, n1
, n2
, SCM_ARG1
, s_lcm
);
494 SCM_GASSERT2 (SCM_INUMP (n2
)
496 || (SCM_NIMP (n2
) && SCM_BIGP (n2
)),
497 g_lcm
, n1
, n2
, SCM_ARGn
, s_lcm
);
501 n2
= SCM_MAKINUM (1L);
506 d
= scm_gcd (n1
, n2
);
509 return scm_abs (scm_product (n1
, scm_quotient (n2
, d
)));
514 #define scm_long2num SCM_MAKINUM
519 SCM_PROC1 (s_logand
, "logand", scm_tc7_asubr
, scm_logand
);
529 return SCM_MAKINUM (-1);
532 return scm_ulong2num (scm_num2ulong (n1
, (char *) SCM_ARG1
, s_logand
)
533 & scm_num2ulong (n2
, (char *) SCM_ARG2
, s_logand
));
536 SCM_PROC1 (s_logior
, "logior", scm_tc7_asubr
, scm_logior
);
549 return scm_ulong2num (scm_num2ulong (n1
, (char *) SCM_ARG1
, s_logior
)
550 | scm_num2ulong (n2
, (char *) SCM_ARG2
, s_logior
));
553 SCM_PROC1 (s_logxor
, "logxor", scm_tc7_asubr
, scm_logxor
);
566 return scm_ulong2num (scm_num2ulong (n1
, (char *) SCM_ARG1
, s_logxor
)
567 ^ scm_num2ulong (n2
, (char *) SCM_ARG2
, s_logxor
));
570 SCM_PROC (s_logtest
, "logtest", 2, 0, 0, scm_logtest
);
577 return ((scm_num2ulong (n1
, (char *) SCM_ARG1
, s_logtest
)
578 & scm_num2ulong (n2
, (char *) SCM_ARG2
, s_logtest
))
579 ? SCM_BOOL_T
: SCM_BOOL_F
);
583 SCM_PROC (s_logbit_p
, "logbit?", 2, 0, 0, scm_logbit_p
);
586 scm_logbit_p (n1
, n2
)
590 return (((1 << scm_num2long (n1
, (char *) SCM_ARG1
, s_logtest
))
591 & scm_num2ulong (n2
, (char *) SCM_ARG2
, s_logtest
))
592 ? SCM_BOOL_T
: SCM_BOOL_F
);
597 SCM_PROC1 (s_logand
, "logand", scm_tc7_asubr
, scm_logand
);
607 return SCM_MAKINUM (-1);
610 return SCM_MAKINUM (SCM_INUM (n1
) & SCM_INUM (n2
));
613 SCM_PROC1 (s_logior
, "logior", scm_tc7_asubr
, scm_logior
);
626 return SCM_MAKINUM (SCM_INUM (n1
) | SCM_INUM (n2
));
629 SCM_PROC1 (s_logxor
, "logxor", scm_tc7_asubr
, scm_logxor
);
642 return SCM_MAKINUM (SCM_INUM (n1
) ^ SCM_INUM (n2
));
645 SCM_PROC (s_logtest
, "logtest", 2, 0, 0, scm_logtest
);
652 SCM_ASSERT (SCM_INUMP (n1
), n1
, SCM_ARG1
, s_logtest
);
653 SCM_ASSERT (SCM_INUMP (n2
), n2
, SCM_ARG2
, s_logtest
);
654 return (SCM_INUM (n1
) & SCM_INUM (n2
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
657 SCM_PROC (s_logbit_p
, "logbit?", 2, 0, 0, scm_logbit_p
);
660 scm_logbit_p (n1
, n2
)
664 SCM_ASSERT (SCM_INUMP (n1
) && SCM_INUM (n1
) >= 0, n1
, SCM_ARG1
, s_logbit_p
);
665 SCM_ASSERT (SCM_INUMP (n2
), n2
, SCM_ARG2
, s_logbit_p
);
666 return ((1 << SCM_INUM (n1
)) & SCM_INUM (n2
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
670 SCM_PROC (s_lognot
, "lognot", 1, 0, 0, scm_lognot
);
676 SCM_ASSERT (SCM_INUMP (n
), n
, SCM_ARG1
, s_lognot
);
677 return scm_difference (SCM_MAKINUM (-1L), n
);
680 SCM_PROC (s_integer_expt
, "integer-expt", 2, 0, 0, scm_integer_expt
);
683 scm_integer_expt (z1
, z2
)
687 SCM acc
= SCM_MAKINUM (1L);
689 if (SCM_INUM0
== z1
|| acc
== z1
)
691 else if (SCM_MAKINUM (-1L) == z1
)
692 return SCM_BOOL_F
== scm_even_p (z2
) ? z1
: acc
;
694 SCM_ASSERT (SCM_INUMP (z2
), z2
, SCM_ARG2
, s_integer_expt
);
699 z1
= scm_divide (z1
, SCM_UNDEFINED
);
706 return scm_product (acc
, z1
);
708 acc
= scm_product (acc
, z1
);
709 z1
= scm_product (z1
, z1
);
714 SCM_PROC (s_ash
, "ash", 2, 0, 0, scm_ash
);
721 SCM res
= SCM_INUM (n
);
722 SCM_ASSERT (SCM_INUMP (cnt
), cnt
, SCM_ARG2
, s_ash
);
726 res
= scm_integer_expt (SCM_MAKINUM (2), SCM_MAKINUM (-SCM_INUM (cnt
)));
727 if (SCM_NFALSEP (scm_negative_p (n
)))
728 return scm_sum (SCM_MAKINUM (-1L),
729 scm_quotient (scm_sum (SCM_MAKINUM (1L), n
), res
));
731 return scm_quotient (n
, res
);
734 return scm_product (n
, scm_integer_expt (SCM_MAKINUM (2), cnt
));
736 SCM_ASSERT (SCM_INUMP (n
), n
, SCM_ARG1
, s_ash
);
737 cnt
= SCM_INUM (cnt
);
739 return SCM_MAKINUM (SCM_SRS (res
, -cnt
));
740 res
= SCM_MAKINUM (res
<< cnt
);
741 if (SCM_INUM (res
) >> cnt
!= SCM_INUM (n
))
742 scm_num_overflow (s_ash
);
747 SCM_PROC (s_bit_extract
, "bit-extract", 3, 0, 0, scm_bit_extract
);
750 scm_bit_extract (n
, start
, end
)
755 SCM_ASSERT (SCM_INUMP (start
), start
, SCM_ARG2
, s_bit_extract
);
756 SCM_ASSERT (SCM_INUMP (end
), end
, SCM_ARG3
, s_bit_extract
);
757 start
= SCM_INUM (start
);
758 end
= SCM_INUM (end
);
759 SCM_ASSERT (end
>= start
, SCM_MAKINUM (end
), SCM_OUTOFRANGE
, s_bit_extract
);
763 scm_logand (scm_difference (scm_integer_expt (SCM_MAKINUM (2),
764 SCM_MAKINUM (end
- start
)),
766 scm_ash (n
, SCM_MAKINUM (-start
)));
768 SCM_ASSERT (SCM_INUMP (n
), n
, SCM_ARG1
, s_bit_extract
);
770 return SCM_MAKINUM ((SCM_INUM (n
) >> start
) & ((1L << (end
- start
)) - 1));
773 static const char scm_logtab
[] = {
774 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
776 SCM_PROC (s_logcount
, "logcount", 1, 0, 0, scm_logcount
);
782 register unsigned long c
= 0;
789 SCM_ASSERT (SCM_NIMP (n
) && SCM_BIGP (n
), n
, SCM_ARG1
, s_logcount
);
791 return scm_logcount (scm_difference (SCM_MAKINUM (-1L), n
));
792 ds
= SCM_BDIGITS (n
);
793 for (i
= SCM_NUMDIGS (n
); i
--;)
794 for (d
= ds
[i
]; d
; d
>>= 4)
795 c
+= scm_logtab
[15 & d
];
796 return SCM_MAKINUM (c
);
799 SCM_ASSERT (SCM_INUMP (n
), n
, SCM_ARG1
, s_logcount
);
801 if ((nn
= SCM_INUM (n
)) < 0)
804 c
+= scm_logtab
[15 & nn
];
805 return SCM_MAKINUM (c
);
808 static const char scm_ilentab
[] = {
809 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
811 SCM_PROC (s_integer_length
, "integer-length", 1, 0, 0, scm_integer_length
);
814 scm_integer_length (n
)
817 register unsigned long c
= 0;
824 SCM_ASSERT (SCM_NIMP (n
) && SCM_BIGP (n
), n
, SCM_ARG1
, s_integer_length
);
826 return scm_integer_length (scm_difference (SCM_MAKINUM (-1L), n
));
827 ds
= SCM_BDIGITS (n
);
828 d
= ds
[c
= SCM_NUMDIGS (n
) - 1];
829 for (c
*= SCM_BITSPERDIG
; d
; d
>>= 4)
832 l
= scm_ilentab
[15 & d
];
834 return SCM_MAKINUM (c
- 4 + l
);
837 SCM_ASSERT (SCM_INUMP (n
), n
, SCM_ARG1
, s_integer_length
);
839 if ((nn
= SCM_INUM (n
)) < 0)
844 l
= scm_ilentab
[15 & nn
];
846 return SCM_MAKINUM (c
- 4 + l
);
851 static const char s_bignum
[] = "bignum";
854 scm_mkbig (nlen
, sign
)
859 /* Cast to SCM to avoid signed/unsigned comparison warnings. */
860 if (((v
<< 16) >> 16) != (SCM
) nlen
)
861 scm_wta (SCM_MAKINUM (nlen
), (char *) SCM_NALLOC
, s_bignum
);
864 SCM_SETCHARS (v
, scm_must_malloc ((long) (nlen
* sizeof (SCM_BIGDIG
)),
866 SCM_SETNUMDIGS (v
, nlen
, sign
? scm_tc16_bigneg
: scm_tc16_bigpos
);
877 unsigned long num
= 0;
878 SCM_BIGDIG
*tmp
= SCM_BDIGITS (b
);
880 num
= SCM_BIGUP (num
) + tmp
[l
];
881 if (SCM_TYP16 (b
) == scm_tc16_bigpos
)
883 if (SCM_POSFIXABLE (num
))
884 return SCM_MAKINUM (num
);
886 else if (SCM_UNEGFIXABLE (num
))
887 return SCM_MAKINUM (-num
);
892 static const char s_adjbig
[] = "scm_adjbig";
899 scm_sizet nsiz
= nlen
;
900 if (((nsiz
<< 16) >> 16) != nlen
)
901 scm_wta (scm_ulong2num (nsiz
), (char *) SCM_NALLOC
, s_adjbig
);
907 scm_must_realloc ((char *) SCM_CHARS (b
),
908 (long) (SCM_NUMDIGS (b
) * sizeof (SCM_BIGDIG
)),
909 (long) (nsiz
* sizeof (SCM_BIGDIG
)), s_adjbig
));
911 SCM_SETCHARS (b
, digits
);
912 SCM_SETNUMDIGS (b
, nsiz
, SCM_TYP16 (b
));
925 scm_sizet nlen
= SCM_NUMDIGS (b
);
927 int nlen
= SCM_NUMDIGS (b
); /* unsigned nlen breaks on Cray when nlen => 0 */
929 SCM_BIGDIG
*zds
= SCM_BDIGITS (b
);
930 while (nlen
-- && !zds
[nlen
]);
932 if (nlen
* SCM_BITSPERDIG
/ SCM_CHAR_BIT
<= sizeof (SCM
))
933 if (SCM_INUMP (b
= scm_big2inum (b
, (scm_sizet
) nlen
)))
935 if (SCM_NUMDIGS (b
) == nlen
)
937 return scm_adjbig (b
, (scm_sizet
) nlen
);
943 scm_copybig (b
, sign
)
947 scm_sizet i
= SCM_NUMDIGS (b
);
948 SCM ans
= scm_mkbig (i
, sign
);
949 SCM_BIGDIG
*src
= SCM_BDIGITS (b
), *dst
= SCM_BDIGITS (ans
);
963 SCM ans
= scm_mkbig (SCM_DIGSPERLONG
, n
< 0);
964 digits
= SCM_BDIGITS (ans
);
967 while (i
< SCM_DIGSPERLONG
)
969 digits
[i
++] = SCM_BIGLO (n
);
970 n
= SCM_BIGDN ((unsigned long) n
);
978 scm_long_long2big (n
)
989 if ((long long) tn
== n
)
990 return scm_long2big (tn
);
996 for (tn
= n
, n_digits
= 0;
998 ++n_digits
, tn
= SCM_BIGDN ((ulong_long
) tn
))
1003 ans
= scm_mkbig (n_digits
, n
< 0);
1004 digits
= SCM_BDIGITS (ans
);
1007 while (i
< n_digits
)
1009 digits
[i
++] = SCM_BIGLO (n
);
1010 n
= SCM_BIGDN ((ulong_long
) n
);
1026 ans
= scm_mkbig (2 * SCM_DIGSPERLONG
, 0);
1027 digits
= SCM_BDIGITS (ans
);
1030 for (i
= 0; i
< SCM_DIGSPERLONG
; ++i
)
1032 digits
[i
] = SCM_BIGLO (n
);
1033 n
= SCM_BIGDN ((unsigned long) n
);
1036 for (i
= 0; i
< SCM_DIGSPERLONG
; ++i
)
1038 digits
[i
+ SCM_DIGSPERLONG
] = SCM_BIGLO (n
);
1039 n
= SCM_BIGDN ((unsigned long) n
);
1052 SCM ans
= scm_mkbig (SCM_DIGSPERLONG
, 0);
1053 digits
= SCM_BDIGITS (ans
);
1054 while (i
< SCM_DIGSPERLONG
)
1056 digits
[i
++] = SCM_BIGLO (n
);
1069 int xsign
= SCM_BIGSIGN (x
);
1070 int ysign
= SCM_BIGSIGN (y
);
1071 scm_sizet xlen
, ylen
;
1073 /* Look at the signs, first. */
1079 /* They're the same sign, so see which one has more digits. Note
1080 that, if they are negative, the longer number is the lesser. */
1081 ylen
= SCM_NUMDIGS (y
);
1082 xlen
= SCM_NUMDIGS (x
);
1084 return (xsign
) ? -1 : 1;
1086 return (xsign
) ? 1 : -1;
1088 /* They have the same number of digits, so find the most significant
1089 digit where they differ. */
1093 if (SCM_BDIGITS (y
)[xlen
] != SCM_BDIGITS (x
)[xlen
])
1094 /* Make the discrimination based on the digit that differs. */
1095 return ((SCM_BDIGITS (y
)[xlen
] > SCM_BDIGITS (x
)[xlen
])
1097 : (xsign
? 1 : -1));
1100 /* The numbers are identical. */
1104 #ifndef SCM_DIGSTOOBIG
1114 SCM_BIGDIG bd
[SCM_DIGSPERLONG
];
1120 while (i
< SCM_DIGSPERLONG
)
1122 p
.bd
[i
++] = SCM_BIGLO (x
);
1125 /* p.bd[0] = SCM_BIGLO(x); p.bd[1] = SCM_BIGDN(x); */
1133 scm_longdigs (x
, digs
)
1140 while (i
< SCM_DIGSPERLONG
)
1142 digs
[i
++] = SCM_BIGLO (x
);
1151 scm_addbig (x
, nx
, xsgn
, bigy
, sgny
)
1158 /* Assumes nx <= SCM_NUMDIGS(bigy) */
1159 /* Assumes xsgn and sgny scm_equal either 0 or 0x0100 */
1161 scm_sizet i
= 0, ny
= SCM_NUMDIGS (bigy
);
1162 SCM z
= scm_copybig (bigy
, SCM_BIGSIGN (bigy
) ^ sgny
);
1163 SCM_BIGDIG
*zds
= SCM_BDIGITS (z
);
1164 if (xsgn
^ SCM_BIGSIGN (z
))
1168 num
+= (long) zds
[i
] - x
[i
];
1171 zds
[i
] = num
+ SCM_BIGRAD
;
1176 zds
[i
] = SCM_BIGLO (num
);
1181 if (num
&& nx
== ny
)
1185 SCM_SETCAR (z
, SCM_CAR (z
) ^ 0x0100);
1188 num
+= (SCM_BIGRAD
- 1) - zds
[i
];
1189 zds
[i
++] = SCM_BIGLO (num
);
1190 num
= SCM_BIGDN (num
);
1200 zds
[i
++] = num
+ SCM_BIGRAD
;
1205 zds
[i
++] = SCM_BIGLO (num
);
1214 num
+= (long) zds
[i
] + x
[i
];
1215 zds
[i
++] = SCM_BIGLO (num
);
1216 num
= SCM_BIGDN (num
);
1224 zds
[i
++] = SCM_BIGLO (num
);
1225 num
= SCM_BIGDN (num
);
1231 z
= scm_adjbig (z
, ny
+ 1);
1232 SCM_BDIGITS (z
)[ny
] = num
;
1236 return scm_normbig (z
);
1241 scm_mulbig (x
, nx
, y
, ny
, sgn
)
1248 scm_sizet i
= 0, j
= nx
+ ny
;
1249 unsigned long n
= 0;
1250 SCM z
= scm_mkbig (j
, sgn
);
1251 SCM_BIGDIG
*zds
= SCM_BDIGITS (z
);
1261 n
+= zds
[i
+ j
] + ((unsigned long) x
[i
] * y
[j
]);
1262 zds
[i
+ j
++] = SCM_BIGLO (n
);
1274 return scm_normbig (z
);
1278 /* Sun's compiler complains about the fact that this function has an
1279 ANSI prototype in numbers.h, but a K&R declaration here, and the
1280 two specify different promotions for the third argument. I'm going
1281 to turn this into an ANSI declaration, and see if anyone complains
1282 about it not being K&R. */
1285 scm_divbigdig (SCM_BIGDIG
* ds
,
1289 register unsigned long t2
= 0;
1292 t2
= SCM_BIGUP (t2
) + ds
[h
];
1302 scm_divbigint (x
, z
, sgn
, mode
)
1312 register unsigned long t2
= 0;
1313 register SCM_BIGDIG
*ds
= SCM_BDIGITS (x
);
1314 scm_sizet nd
= SCM_NUMDIGS (x
);
1316 t2
= (SCM_BIGUP (t2
) + ds
[nd
]) % z
;
1319 return SCM_MAKINUM (sgn
? -t2
: t2
);
1322 #ifndef SCM_DIGSTOOBIG
1323 unsigned long t2
= scm_pseudolong (z
);
1324 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
1325 (SCM_BIGDIG
*) & t2
, SCM_DIGSPERLONG
,
1328 SCM_BIGDIG t2
[SCM_DIGSPERLONG
];
1329 scm_longdigs (z
, t2
);
1330 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
1331 t2
, SCM_DIGSPERLONG
,
1339 scm_divbigbig (x
, nx
, y
, ny
, sgn
, modes
)
1347 /* modes description
1351 3 quotient but returns 0 if division is not exact. */
1352 scm_sizet i
= 0, j
= 0;
1354 unsigned long t2
= 0;
1356 SCM_BIGDIG d
= 0, qhat
, *zds
, *yds
;
1357 /* algorithm requires nx >= ny */
1361 case 0: /* remainder -- just return x */
1362 z
= scm_mkbig (nx
, sgn
);
1363 zds
= SCM_BDIGITS (z
);
1370 case 1: /* scm_modulo -- return y-x */
1371 z
= scm_mkbig (ny
, sgn
);
1372 zds
= SCM_BDIGITS (z
);
1375 num
+= (long) y
[i
] - x
[i
];
1378 zds
[i
] = num
+ SCM_BIGRAD
;
1393 zds
[i
++] = num
+ SCM_BIGRAD
;
1404 return SCM_INUM0
; /* quotient is zero */
1406 return 0; /* the division is not exact */
1409 z
= scm_mkbig (nx
== ny
? nx
+ 2 : nx
+ 1, sgn
);
1410 zds
= SCM_BDIGITS (z
);
1414 ny
--; /* in case y came in as a psuedolong */
1415 if (y
[ny
- 1] < (SCM_BIGRAD
>> 1))
1416 { /* normalize operands */
1417 d
= SCM_BIGRAD
/ (y
[ny
- 1] + 1);
1418 newy
= scm_mkbig (ny
, 0);
1419 yds
= SCM_BDIGITS (newy
);
1422 t2
+= (unsigned long) y
[j
] * d
;
1423 yds
[j
++] = SCM_BIGLO (t2
);
1424 t2
= SCM_BIGDN (t2
);
1431 t2
+= (unsigned long) x
[j
] * d
;
1432 zds
[j
++] = SCM_BIGLO (t2
);
1433 t2
= SCM_BIGDN (t2
);
1443 j
= nx
== ny
? nx
+ 1 : nx
; /* dividend needs more digits than divisor */
1445 { /* loop over digits of quotient */
1446 if (zds
[j
] == y
[ny
- 1])
1447 qhat
= SCM_BIGRAD
- 1;
1449 qhat
= (SCM_BIGUP (zds
[j
]) + zds
[j
- 1]) / y
[ny
- 1];
1456 { /* multiply and subtract */
1457 t2
+= (unsigned long) y
[i
] * qhat
;
1458 num
+= zds
[j
- ny
+ i
] - SCM_BIGLO (t2
);
1461 zds
[j
- ny
+ i
] = num
+ SCM_BIGRAD
;
1466 zds
[j
- ny
+ i
] = num
;
1469 t2
= SCM_BIGDN (t2
);
1472 num
+= zds
[j
- ny
+ i
] - t2
; /* borrow from high digit; don't update */
1474 { /* "add back" required */
1480 num
+= (long) zds
[j
- ny
+ i
] + y
[i
];
1481 zds
[j
- ny
+ i
] = SCM_BIGLO (num
);
1482 num
= SCM_BIGDN (num
);
1493 case 3: /* check that remainder==0 */
1494 for (j
= ny
; j
&& !zds
[j
- 1]; --j
);
1497 case 2: /* move quotient down in z */
1498 j
= (nx
== ny
? nx
+ 2 : nx
+ 1) - ny
;
1499 for (i
= 0; i
< j
; i
++)
1500 zds
[i
] = zds
[i
+ ny
];
1503 case 1: /* subtract for scm_modulo */
1509 num
+= y
[i
] - zds
[i
];
1513 zds
[i
] = num
+ SCM_BIGRAD
;
1525 case 0: /* just normalize remainder */
1527 scm_divbigdig (zds
, ny
, d
);
1530 for (j
= ny
; j
&& !zds
[j
- 1]; --j
);
1531 if (j
* SCM_BITSPERDIG
<= sizeof (SCM
) * SCM_CHAR_BIT
)
1532 if (SCM_INUMP (z
= scm_big2inum (z
, j
)))
1534 return scm_adjbig (z
, j
);
1542 /*** NUMBERS -> STRINGS ***/
1545 static const double fx
[] =
1546 { 0.0, 5e-1, 5e-2, 5e-3, 5e-4, 5e-5,
1547 5e-6, 5e-7, 5e-8, 5e-9, 5e-10,
1548 5e-11, 5e-12, 5e-13, 5e-14, 5e-15,
1549 5e-16, 5e-17, 5e-18, 5e-19, 5e-20};
1554 static scm_sizet idbl2str
SCM_P ((double f
, char *a
));
1561 int efmt
, dpt
, d
, i
, wp
= scm_dblprec
;
1566 goto zero
; /*{a[0]='0'; a[1]='.'; a[2]='0'; return 3;} */
1585 #ifdef DBL_MIN_10_EXP /* Prevent unnormalized values, as from
1586 make-uniform-vector, from causing infinite loops. */
1590 if (exp
-- < DBL_MIN_10_EXP
)
1596 if (exp
++ > DBL_MAX_10_EXP
)
1611 if (f
+ fx
[wp
] >= 10.0)
1618 dpt
= (exp
+ 9999) % 3;
1622 efmt
= (exp
< -3) || (exp
> wp
+ 2);
1647 if (f
+ fx
[wp
] >= 1.0)
1661 if ((dpt
> 4) && (exp
> 6))
1663 d
= (a
[0] == '-' ? 2 : 1);
1664 for (i
= ch
++; i
> d
; i
--)
1677 if (a
[ch
- 1] == '.')
1678 a
[ch
++] = '0'; /* trailing zero */
1687 for (i
= 10; i
<= exp
; i
*= 10);
1688 for (i
/= 10; i
; i
/= 10)
1690 a
[ch
++] = exp
/ i
+ '0';
1698 static scm_sizet iflo2str
SCM_P ((SCM flt
, char *str
));
1707 if (SCM_SINGP (flt
))
1708 i
= idbl2str (SCM_FLO (flt
), str
);
1711 i
= idbl2str (SCM_REAL (flt
), str
);
1712 if (SCM_CPLXP (flt
))
1714 if (0 <= SCM_IMAG (flt
)) /* jeh */
1715 str
[i
++] = '+'; /* jeh */
1716 i
+= idbl2str (SCM_IMAG (flt
), &str
[i
]);
1721 #endif /* SCM_FLOATS */
1725 scm_iint2str (num
, rad
, p
)
1731 register int i
= 1, d
;
1732 register long n
= num
;
1738 for (n
/= rad
; n
> 0; n
/= rad
)
1752 p
[i
] = d
+ ((d
< 10) ? '0' : 'a' - 10);
1760 static SCM big2str
SCM_P ((SCM b
, register unsigned int radix
));
1765 register unsigned int radix
;
1767 SCM t
= scm_copybig (b
, 0); /* sign of temp doesn't matter */
1768 register SCM_BIGDIG
*ds
= SCM_BDIGITS (t
);
1769 scm_sizet i
= SCM_NUMDIGS (t
);
1770 scm_sizet j
= radix
== 16 ? (SCM_BITSPERDIG
* i
) / 4 + 2
1771 : radix
>= 10 ? (SCM_BITSPERDIG
* i
* 241L) / 800 + 2
1772 : (SCM_BITSPERDIG
* i
) + 2;
1774 scm_sizet radct
= 0;
1775 scm_sizet ch
; /* jeh */
1776 SCM_BIGDIG radpow
= 1, radmod
= 0;
1777 SCM ss
= scm_makstr ((long) j
, 0);
1778 char *s
= SCM_CHARS (ss
), c
;
1779 while ((long) radpow
* radix
< SCM_BIGRAD
)
1784 s
[0] = scm_tc16_bigneg
== SCM_TYP16 (b
) ? '-' : '+';
1785 while ((i
|| radmod
) && j
)
1789 radmod
= (SCM_BIGDIG
) scm_divbigdig (ds
, i
, radpow
);
1797 s
[--j
] = c
< 10 ? c
+ '0' : c
+ 'a' - 10;
1799 ch
= s
[0] == '-' ? 1 : 0; /* jeh */
1802 for (i
= j
; j
< SCM_LENGTH (ss
); j
++)
1803 s
[ch
+ j
- i
] = s
[j
]; /* jeh */
1804 scm_vector_set_length_x (ss
, /* jeh */
1805 (SCM
) SCM_MAKINUM (ch
+ SCM_LENGTH (ss
) - i
));
1808 return scm_return_first (ss
, t
);
1813 SCM_PROC (s_number_to_string
, "number->string", 1, 1, 0, scm_number_to_string
);
1816 scm_number_to_string (x
, radix
)
1820 if (SCM_UNBNDP (radix
))
1821 radix
= SCM_MAKINUM (10L);
1824 SCM_ASSERT (SCM_INUMP (radix
), radix
, SCM_ARG2
, s_number_to_string
);
1825 SCM_ASSERT (SCM_INUM (radix
) >= 2, radix
, SCM_OUTOFRANGE
,
1826 s_number_to_string
);
1831 char num_buf
[SCM_FLOBUFLEN
];
1833 SCM_ASRTGO (SCM_NIMP (x
), badx
);
1835 return big2str (x
, (unsigned int) SCM_INUM (radix
));
1836 #ifndef SCM_RECKLESS
1837 if (!(SCM_INEXP (x
)))
1840 scm_wta (x
, (char *) SCM_ARG1
, s_number_to_string
);
1844 SCM_ASSERT (SCM_NIMP (x
) && SCM_INEXP (x
),
1845 x
, SCM_ARG1
, s_number_to_string
);
1847 return scm_makfromstr (num_buf
, iflo2str (x
, num_buf
), 0);
1853 SCM_ASSERT (SCM_NIMP (x
) && SCM_BIGP (x
),
1854 x
, SCM_ARG1
, s_number_to_string
);
1855 return big2str (x
, (unsigned int) SCM_INUM (radix
));
1858 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_number_to_string
);
1862 char num_buf
[SCM_INTBUFLEN
];
1863 return scm_makfromstr (num_buf
,
1864 scm_iint2str (SCM_INUM (x
),
1865 (int) SCM_INUM (radix
),
1872 /* These print routines are stubbed here so that scm_repl.c doesn't need
1873 SCM_FLOATS or SCM_BIGDIGs conditionals */
1876 scm_floprint (sexp
, port
, pstate
)
1879 scm_print_state
*pstate
;
1882 char num_buf
[SCM_FLOBUFLEN
];
1883 scm_lfwrite (num_buf
, iflo2str (sexp
, num_buf
), port
);
1885 scm_ipruk ("float", sexp
, port
);
1893 scm_bigprint (exp
, port
, pstate
)
1896 scm_print_state
*pstate
;
1899 exp
= big2str (exp
, (unsigned int) 10);
1900 scm_lfwrite (SCM_CHARS (exp
), (scm_sizet
) SCM_LENGTH (exp
), port
);
1902 scm_ipruk ("bignum", exp
, port
);
1906 /*** END nums->strs ***/
1908 /*** STRINGS -> NUMBERS ***/
1910 static SCM scm_small_istr2int
SCM_P ((char *str
, long len
, long radix
));
1913 scm_small_istr2int (str
, len
, radix
)
1918 register long n
= 0, ln
;
1923 return SCM_BOOL_F
; /* zero scm_length */
1925 { /* leading sign */
1930 return SCM_BOOL_F
; /* bad if lone `+' or `-' */
1935 switch (c
= str
[i
++])
1957 return SCM_BOOL_F
; /* bad digit for radix */
1960 /* Negation is a workaround for HP700 cc bug */
1961 if (n
> ln
|| (-n
> -SCM_MOST_NEGATIVE_FIXNUM
))
1965 return SCM_BOOL_F
; /* not a digit */
1970 if ((n
= -n
) > SCM_MOST_POSITIVE_FIXNUM
)
1972 return SCM_MAKINUM (n
);
1973 ovfl
: /* overflow scheme integer */
1980 scm_istr2int (str
, len
, radix
)
1986 register scm_sizet k
, blen
= 1;
1990 register SCM_BIGDIG
*ds
;
1991 register unsigned long t2
;
1994 return SCM_BOOL_F
; /* zero scm_length */
1996 /* Short numbers we parse directly into an int, to avoid the overhead
1997 of creating a bignum. */
1999 return scm_small_istr2int (str
, len
, radix
);
2002 j
= 1 + (4 * len
* sizeof (char)) / (SCM_BITSPERDIG
);
2003 else if (10 <= radix
)
2004 j
= 1 + (84 * len
* sizeof (char)) / (SCM_BITSPERDIG
* 25);
2006 j
= 1 + (len
* sizeof (char)) / (SCM_BITSPERDIG
);
2008 { /* leading sign */
2011 if (++i
== (unsigned) len
)
2012 return SCM_BOOL_F
; /* bad if lone `+' or `-' */
2014 res
= scm_mkbig (j
, '-' == str
[0]);
2015 ds
= SCM_BDIGITS (res
);
2020 switch (c
= str
[i
++])
2042 return SCM_BOOL_F
; /* bad digit for radix */
2048 /* printf ("k = %d, blen = %d, t2 = %ld, ds[k] = %d\n", k, blen, t2, ds[k]); */
2049 t2
+= ds
[k
] * radix
;
2050 ds
[k
++] = SCM_BIGLO (t2
);
2051 t2
= SCM_BIGDN (t2
);
2054 scm_num_overflow ("bignum");
2062 return SCM_BOOL_F
; /* not a digit */
2065 while (i
< (unsigned) len
);
2066 if (blen
* SCM_BITSPERDIG
/ SCM_CHAR_BIT
<= sizeof (SCM
))
2067 if (SCM_INUMP (res
= scm_big2inum (res
, blen
)))
2071 return scm_adjbig (res
, blen
);
2077 scm_istr2flo (str
, len
, radix
)
2082 register int c
, i
= 0;
2084 double res
= 0.0, tmp
= 0.0;
2090 return SCM_BOOL_F
; /* zero scm_length */
2093 { /* leading sign */
2106 return SCM_BOOL_F
; /* bad if lone `+' or `-' */
2108 if (str
[i
] == 'i' || str
[i
] == 'I')
2109 { /* handle `+i' and `-i' */
2110 if (lead_sgn
== 0.0)
2111 return SCM_BOOL_F
; /* must have leading sign */
2113 return SCM_BOOL_F
; /* `i' not last character */
2114 return scm_makdbl (0.0, lead_sgn
);
2117 { /* check initial digits */
2127 goto out1
; /* must be exponent */
2144 return SCM_BOOL_F
; /* bad digit for radix */
2145 res
= res
* radix
+ c
;
2146 flg
= 1; /* res is valid */
2155 /* if true, then we did see a digit above, and res is valid */
2159 /* By here, must have seen a digit,
2160 or must have next char be a `.' with radix==10 */
2162 if (!(str
[i
] == '.' && radix
== 10))
2165 while (str
[i
] == '#')
2166 { /* optional sharps */
2199 tmp
= tmp
* radix
+ c
;
2207 return SCM_BOOL_F
; /* `slash zero' not allowed */
2209 while (str
[i
] == '#')
2210 { /* optional sharps */
2220 { /* decimal point notation */
2222 return SCM_BOOL_F
; /* must be radix 10 */
2229 res
= res
* 10.0 + c
- '0';
2238 return SCM_BOOL_F
; /* no digits before or after decimal point */
2241 while (str
[i
] == '#')
2242 { /* ignore remaining sharps */
2261 int expsgn
= 1, expon
= 0;
2263 return SCM_BOOL_F
; /* only in radix 10 */
2265 return SCM_BOOL_F
; /* bad exponent */
2272 return SCM_BOOL_F
; /* bad exponent */
2274 if (str
[i
] < '0' || str
[i
] > '9')
2275 return SCM_BOOL_F
; /* bad exponent */
2281 expon
= expon
* 10 + c
- '0';
2283 return SCM_BOOL_F
; /* exponent too large */
2291 point
+= expsgn
* expon
;
2309 /* at this point, we have a legitimate floating point result */
2310 if (lead_sgn
== -1.0)
2313 return scm_makdbl (res
, 0.0);
2315 if (str
[i
] == 'i' || str
[i
] == 'I')
2316 { /* pure imaginary number */
2317 if (lead_sgn
== 0.0)
2318 return SCM_BOOL_F
; /* must have leading sign */
2320 return SCM_BOOL_F
; /* `i' not last character */
2321 return scm_makdbl (0.0, res
);
2333 { /* polar input for complex number */
2334 /* get a `real' for scm_angle */
2335 second
= scm_istr2flo (&str
[i
], (long) (len
- i
), radix
);
2336 if (!(SCM_NIMP (second
) && SCM_INEXP (second
)))
2337 return SCM_BOOL_F
; /* not `real' */
2338 if (SCM_CPLXP (second
))
2339 return SCM_BOOL_F
; /* not `real' */
2340 tmp
= SCM_REALPART (second
);
2341 return scm_makdbl (res
* cos (tmp
), res
* sin (tmp
));
2347 /* at this point, last char must be `i' */
2348 if (str
[len
- 1] != 'i' && str
[len
- 1] != 'I')
2350 /* handles `x+i' and `x-i' */
2352 return scm_makdbl (res
, lead_sgn
);
2353 /* get a `ureal' for complex part */
2354 second
= scm_istr2flo (&str
[i
], (long) ((len
- i
) - 1), radix
);
2355 if (! (SCM_NIMP (second
) && SCM_INEXP (second
)))
2356 return SCM_BOOL_F
; /* not `ureal' */
2357 if (SCM_CPLXP (second
))
2358 return SCM_BOOL_F
; /* not `ureal' */
2359 tmp
= SCM_REALPART (second
);
2361 return SCM_BOOL_F
; /* not `ureal' */
2362 return scm_makdbl (res
, (lead_sgn
* tmp
));
2364 #endif /* SCM_FLOATS */
2369 scm_istring2number (str
, len
, radix
)
2376 char ex_p
= 0, rx_p
= 0; /* Only allow 1 exactness and 1 radix prefix */
2379 if (*str
== '+' || *str
== '-') /* Catches lone `+' and `-' for speed */
2382 while ((len
- i
) >= 2 && str
[i
] == '#' && ++i
)
2428 return scm_istr2int (&str
[i
], len
- i
, radix
);
2430 res
= scm_istr2int (&str
[i
], len
- i
, radix
);
2431 if (SCM_NFALSEP (res
))
2435 return scm_istr2flo (&str
[i
], len
- i
, radix
);
2442 SCM_PROC (s_string_to_number
, "string->number", 1, 1, 0, scm_string_to_number
);
2445 scm_string_to_number (str
, radix
)
2450 if (SCM_UNBNDP (radix
))
2451 radix
= SCM_MAKINUM (10L);
2454 SCM_ASSERT (SCM_INUMP (radix
), radix
, SCM_ARG2
, s_string_to_number
);
2455 SCM_ASSERT (SCM_INUM (radix
) >= 2, radix
, SCM_OUTOFRANGE
,
2456 s_number_to_string
);
2458 SCM_ASSERT (SCM_NIMP (str
) && SCM_ROSTRINGP (str
),
2459 str
, SCM_ARG1
, s_string_to_number
);
2460 answer
= scm_istring2number (SCM_ROCHARS (str
),
2463 return scm_return_first (answer
, str
);
2465 /*** END strs->nums ***/
2475 if ((y
== 0.0) && (x
== 0.0))
2482 #ifndef SCM_SINGLESONLY
2483 if ((-FLTMAX
< x
) && (x
< FLTMAX
) && (fx
== x
))
2486 SCM_NEWSMOB(z
,scm_tc_flo
,NULL
);
2491 #endif /* def SCM_SINGLES */
2492 SCM_NEWSMOB(z
,scm_tc_dblr
,scm_must_malloc (1L * sizeof (double), "real"));
2496 SCM_NEWSMOB(z
,scm_tc_dblc
,scm_must_malloc (2L * sizeof (double), "comkplex"));
2513 if (0 == scm_bigcomp (x
, y
))
2527 if (SCM_REALPART (x
) != SCM_REALPART (y
))
2529 if (!(SCM_CPLXP (x
) && (SCM_IMAG (x
) != SCM_IMAG (y
))))
2538 SCM_PROC (s_number_p
, "number?", 1, 0, 0, scm_number_p
);
2539 SCM_PROC (s_complex_p
, "complex?", 1, 0, 0, scm_number_p
);
2548 if (SCM_NIMP (x
) && SCM_NUMP (x
))
2552 if (SCM_NIMP (x
) && SCM_NUMP (x
))
2562 SCM_PROC (s_real_p
, "real?", 1, 0, 0, scm_real_p
);
2563 SCM_PROC (s_rational_p
, "rational?", 1, 0, 0, scm_real_p
);
2584 SCM_PROC (s_int_p
, "integer?", 1, 0, 0, scm_integer_p
);
2603 r
= SCM_REALPART (x
);
2611 #endif /* SCM_FLOATS */
2613 SCM_PROC (s_inexact_p
, "inexact?", 1, 0, 0, scm_inexact_p
);
2620 if (SCM_NIMP (x
) && SCM_INEXP (x
))
2629 SCM_GPROC1 (s_eq_p
, "=", scm_tc7_rpsubr
, scm_num_eq_p
, g_eq_p
);
2641 if (!(SCM_NIMP (x
)))
2644 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 if (!(SCM_INEXP (y
)))
2701 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2704 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
2707 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2711 return ((SCM_REALP (y
) && (((double) SCM_INUM (x
)) == SCM_REALPART (y
)))
2719 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
2720 g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2723 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
2724 return (0 == scm_bigcomp (x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2728 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
2731 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2736 SCM_GASSERT2 (SCM_INUMP (x
), g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2737 SCM_GASSERT2 (SCM_INUMP (y
), g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2740 return ((long) x
== (long) y
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2745 SCM_GPROC1 (s_less_p
, "<", scm_tc7_rpsubr
, scm_less_p
, g_less_p
);
2756 if (!(SCM_NIMP (x
)))
2759 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2764 return SCM_BIGSIGN (x
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2765 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2767 return (1 == scm_bigcomp (x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2768 SCM_ASRTGO (SCM_REALP (y
), bady
);
2769 return ((scm_big2dbl (x
) < SCM_REALPART (y
))
2773 SCM_ASRTGO (SCM_REALP (x
), badx
);
2775 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_REALP (x
),
2776 g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2779 return ((SCM_REALPART (x
) < ((double) SCM_INUM (y
)))
2783 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2785 return (SCM_REALPART (x
) < scm_big2dbl (y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2786 SCM_ASRTGO (SCM_REALP (y
), bady
);
2788 SCM_ASRTGO (SCM_NIMP (y
) && SCM_REALP (y
), bady
);
2790 return (SCM_REALPART (x
) < SCM_REALPART (y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2795 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2797 return SCM_BIGSIGN (y
) ? SCM_BOOL_F
: SCM_BOOL_T
;
2798 if (!(SCM_REALP (y
)))
2801 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2804 if (!(SCM_NIMP (y
) && SCM_REALP (y
)))
2807 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2810 return ((((double) SCM_INUM (x
)) < SCM_REALPART (y
))
2818 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
2819 g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2821 return SCM_BIGSIGN (x
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2822 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
2823 return (1 == scm_bigcomp (x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2827 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
2830 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2832 return SCM_BIGSIGN (y
) ? SCM_BOOL_F
: SCM_BOOL_T
;
2835 SCM_GASSERT2 (SCM_INUMP (x
), g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2836 SCM_GASSERT2 (SCM_INUMP (y
), g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2839 return ((long) x
< (long) y
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2843 SCM_PROC1 (s_gr_p
, ">", scm_tc7_rpsubr
, scm_gr_p
);
2850 return scm_less_p (y
, x
);
2855 SCM_PROC1 (s_leq_p
, "<=", scm_tc7_rpsubr
, scm_leq_p
);
2862 return SCM_BOOL_NOT (scm_less_p (y
, x
));
2867 SCM_PROC1 (s_geq_p
, ">=", scm_tc7_rpsubr
, scm_geq_p
);
2874 return SCM_BOOL_NOT (scm_less_p (x
, y
));
2879 SCM_GPROC (s_zero_p
, "zero?", 1, 0, 0, scm_zero_p
, g_zero_p
);
2889 SCM_ASRTGO (SCM_NIMP (z
), badz
);
2892 if (!(SCM_INEXP (z
)))
2895 SCM_WTA_DISPATCH_1 (g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2898 SCM_GASSERT1 (SCM_NIMP (z
) && SCM_INEXP (z
),
2899 g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2901 return (z
== scm_flo0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2907 SCM_GASSERT1 (SCM_NIMP (z
) && SCM_BIGP (z
),
2908 g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2912 SCM_GASSERT1 (SCM_INUMP (z
), g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2915 return (z
== SCM_INUM0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2920 SCM_GPROC (s_positive_p
, "positive?", 1, 0, 0, scm_positive_p
, g_positive_p
);
2930 SCM_ASRTGO (SCM_NIMP (x
), badx
);
2932 return SCM_TYP16 (x
) == scm_tc16_bigpos
? SCM_BOOL_T
: SCM_BOOL_F
;
2933 if (!(SCM_REALP (x
)))
2936 SCM_WTA_DISPATCH_1 (g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2939 SCM_GASSERT1 (SCM_NIMP (x
) && SCM_REALP (x
),
2940 g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2942 return (SCM_REALPART (x
) > 0.0) ? SCM_BOOL_T
: SCM_BOOL_F
;
2948 SCM_GASSERT1 (SCM_NIMP (x
) && SCM_BIGP (x
),
2949 g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2950 return SCM_TYP16 (x
) == scm_tc16_bigpos
? SCM_BOOL_T
: SCM_BOOL_F
;
2953 SCM_GASSERT1 (SCM_INUMP (x
), g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2956 return (x
> SCM_INUM0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2961 SCM_GPROC (s_negative_p
, "negative?", 1, 0, 0, scm_negative_p
, g_negative_p
);
2971 SCM_ASRTGO (SCM_NIMP (x
), badx
);
2973 return SCM_TYP16 (x
) == scm_tc16_bigpos
? SCM_BOOL_F
: SCM_BOOL_T
;
2974 if (!(SCM_REALP (x
)))
2977 SCM_WTA_DISPATCH_1 (g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2980 SCM_GASSERT1 (SCM_NIMP (x
) && SCM_REALP (x
),
2981 g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2983 return (SCM_REALPART (x
) < 0.0) ? SCM_BOOL_T
: SCM_BOOL_F
;
2989 SCM_GASSERT1 (SCM_NIMP (x
) && SCM_BIGP (x
),
2990 g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2991 return (SCM_TYP16 (x
) == scm_tc16_bigneg
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2994 SCM_GASSERT1 (SCM_INUMP (x
), g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2997 return (x
< SCM_INUM0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
3001 SCM_GPROC1 (s_max
, "max", scm_tc7_asubr
, scm_max
, g_max
);
3013 SCM_GASSERT0 (!SCM_UNBNDP (x
),
3014 g_max
, scm_makfrom0str (s_max
), SCM_WNA
, 0);
3015 SCM_GASSERT1 (SCM_NUMBERP (x
), g_max
, x
, SCM_ARG1
, s_max
);
3025 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARG1
, s_max
);
3030 return SCM_BIGSIGN (x
) ? y
: x
;
3031 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3033 return (1 == scm_bigcomp (x
, y
)) ? y
: x
;
3034 SCM_ASRTGO (SCM_REALP (y
), bady
);
3035 z
= scm_big2dbl (x
);
3036 return (z
< SCM_REALPART (y
)) ? y
: scm_makdbl (z
, 0.0);
3038 SCM_ASRTGO (SCM_REALP (x
), badx2
);
3040 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_REALP (x
),
3041 g_max
, x
, y
, SCM_ARG1
, s_max
);
3044 return ((SCM_REALPART (x
) < (z
= SCM_INUM (y
)))
3045 ? scm_makdbl (z
, 0.0)
3048 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3050 return ((SCM_REALPART (x
) < (z
= scm_big2dbl (y
)))
3051 ? scm_makdbl (z
, 0.0)
3053 SCM_ASRTGO (SCM_REALP (y
), bady
);
3055 SCM_ASRTGO (SCM_NIMP (y
) && SCM_REALP (y
), bady
);
3057 return (SCM_REALPART (x
) < SCM_REALPART (y
)) ? y
: x
;
3062 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3064 return SCM_BIGSIGN (y
) ? x
: y
;
3065 if (!(SCM_REALP (y
)))
3068 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARGn
, s_max
);
3071 if (!(SCM_NIMP (y
) && SCM_REALP (y
)))
3074 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARGn
, s_max
);
3077 return (((z
= SCM_INUM (x
)) < SCM_REALPART (y
))
3079 : scm_makdbl (z
, 0.0));
3085 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
3086 g_max
, x
, y
, SCM_ARG1
, s_max
);
3088 return SCM_BIGSIGN (x
) ? y
: x
;
3089 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3090 return (1 == scm_bigcomp (x
, y
)) ? y
: x
;
3094 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3097 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARGn
, s_max
);
3099 return SCM_BIGSIGN (y
) ? x
: y
;
3102 SCM_GASSERT2 (SCM_INUMP (x
), g_max
, x
, y
, SCM_ARG1
, s_max
);
3103 SCM_GASSERT2 (SCM_INUMP (y
), g_max
, x
, y
, SCM_ARGn
, s_max
);
3106 return ((long) x
< (long) y
) ? y
: x
;
3112 SCM_GPROC1 (s_min
, "min", scm_tc7_asubr
, scm_min
, g_min
);
3124 SCM_GASSERT0 (!SCM_UNBNDP (x
),
3125 g_min
, scm_makfrom0str (s_min
), SCM_WNA
, 0);
3126 SCM_GASSERT1 (SCM_NUMBERP (x
), g_min
, x
, SCM_ARG1
, s_min
);
3133 if (!(SCM_NIMP (x
)))
3136 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARG1
, s_min
);
3141 return SCM_BIGSIGN (x
) ? x
: y
;
3142 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3144 return (-1 == scm_bigcomp (x
, y
)) ? y
: x
;
3145 SCM_ASRTGO (SCM_REALP (y
), bady
);
3146 z
= scm_big2dbl (x
);
3147 return (z
> SCM_REALPART (y
)) ? y
: scm_makdbl (z
, 0.0);
3149 SCM_ASRTGO (SCM_REALP (x
), badx2
);
3151 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_REALP (x
),
3152 g_min
, x
, y
, SCM_ARG1
, s_min
);
3155 return ((SCM_REALPART (x
) > (z
= SCM_INUM (y
)))
3156 ? scm_makdbl (z
, 0.0)
3159 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3161 return ((SCM_REALPART (x
) > (z
= scm_big2dbl (y
)))
3162 ? scm_makdbl (z
, 0.0)
3164 SCM_ASRTGO (SCM_REALP (y
), bady
);
3166 SCM_ASRTGO (SCM_NIMP (y
) && SCM_REALP (y
), bady
);
3168 return (SCM_REALPART (x
) > SCM_REALPART (y
)) ? y
: x
;
3173 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3175 return SCM_BIGSIGN (y
) ? y
: x
;
3176 if (!(SCM_REALP (y
)))
3179 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARGn
, s_min
);
3182 if (!(SCM_NIMP (y
) && SCM_REALP (y
)))
3185 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARGn
, s_min
);
3188 return (((z
= SCM_INUM (x
)) > SCM_REALPART (y
))
3190 : scm_makdbl (z
, 0.0));
3196 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
3197 g_min
, x
, y
, SCM_ARG1
, s_min
);
3199 return SCM_BIGSIGN (x
) ? x
: y
;
3200 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3201 return (-1 == scm_bigcomp (x
, y
)) ? y
: x
;
3205 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3208 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARGn
, s_min
);
3210 return SCM_BIGSIGN (y
) ? y
: x
;
3213 SCM_GASSERT2 (SCM_INUMP (x
), g_min
, x
, y
, SCM_ARG1
, s_min
);
3214 SCM_GASSERT2 (SCM_INUMP (y
), g_min
, x
, y
, SCM_ARGn
, s_min
);
3217 return ((long) x
> (long) y
) ? y
: x
;
3223 SCM_GPROC1 (s_sum
, "+", scm_tc7_asubr
, scm_sum
, g_sum
);
3234 SCM_GASSERT1 (SCM_NUMBERP (x
), g_sum
, x
, SCM_ARG1
, s_sum
);
3245 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARG1
, s_sum
);
3256 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3259 if (SCM_NUMDIGS (x
) > SCM_NUMDIGS (y
))
3265 return scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3269 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3271 return scm_makdbl (scm_big2dbl (x
) + SCM_REALPART (y
),
3272 SCM_CPLXP (y
) ? SCM_IMAG (y
) : 0.0);
3274 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3276 SCM_ASRTGO (SCM_NIMP (x
) && SCM_INEXP (x
), badx2
);
3286 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3294 else if (!(SCM_INEXP (y
)))
3297 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3300 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
3303 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3312 return scm_makdbl (SCM_REALPART (x
) + SCM_REALPART (y
), i
);
3318 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3323 #ifndef SCM_DIGSTOOBIG
3324 long z
= scm_pseudolong (SCM_INUM (x
));
3325 return scm_addbig ((SCM_BIGDIG
*) & z
,
3327 (x
< 0) ? 0x0100 : 0,
3330 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3331 scm_longdigs (SCM_INUM (x
), zdigs
);
3332 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3337 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3339 SCM_ASRTGO (SCM_NIMP (y
) && SCM_INEXP (y
), bady
);
3342 return scm_makdbl (SCM_INUM (x
) + SCM_REALPART (y
),
3343 SCM_CPLXP (y
) ? SCM_IMAG (y
) : 0.0);
3350 SCM_ASRTGO (SCM_NIMP (x
) && SCM_BIGP (x
), badx2
);
3358 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3359 if (SCM_NUMDIGS (x
) > SCM_NUMDIGS (y
))
3365 return scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
), SCM_BIGSIGN (x
),
3370 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3373 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3377 #ifndef SCM_DIGSTOOBIG
3378 long z
= scm_pseudolong (SCM_INUM (x
));
3379 return scm_addbig (&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
3381 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3382 scm_longdigs (SCM_INUM (x
), zdigs
);
3383 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
3388 SCM_ASRTGO (SCM_INUMP (x
), badx2
);
3389 SCM_GASSERT2 (SCM_INUMP (y
), g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3392 x
= SCM_INUM (x
) + SCM_INUM (y
);
3393 if (SCM_FIXABLE (x
))
3394 return SCM_MAKINUM (x
);
3396 return scm_long2big (x
);
3399 return scm_makdbl ((double) x
, 0.0);
3401 scm_num_overflow (s_sum
);
3402 return SCM_UNSPECIFIED
;
3410 SCM_GPROC1 (s_difference
, "-", scm_tc7_asubr
, scm_difference
, g_difference
);
3413 scm_difference (x
, y
)
3420 if (!(SCM_NIMP (x
)))
3424 SCM_GASSERT0 (!SCM_UNBNDP (x
), g_difference
,
3425 scm_makfrom0str (s_difference
), SCM_WNA
, 0);
3427 SCM_WTA_DISPATCH_1 (g_difference
, x
, SCM_ARG1
, s_difference
);
3432 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARG1
, s_difference
);
3440 x
= scm_copybig (x
, !SCM_BIGSIGN (x
));
3441 return (SCM_NUMDIGS (x
) * SCM_BITSPERDIG
/ SCM_CHAR_BIT
3443 ? scm_big2inum (x
, SCM_NUMDIGS (x
))
3447 SCM_ASRTGO (SCM_INEXP (x
), badx
);
3448 return scm_makdbl (- SCM_REALPART (x
),
3449 SCM_CPLXP (x
) ? -SCM_IMAG (x
) : 0.0);
3452 return scm_sum (x
, SCM_MAKINUM (- SCM_INUM (y
)));
3454 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3458 return ((SCM_NUMDIGS (x
) < SCM_NUMDIGS (y
))
3459 ? scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3462 : scm_addbig (SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3463 SCM_BIGSIGN (y
) ^ 0x0100,
3465 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3466 return scm_makdbl (scm_big2dbl (x
) - SCM_REALPART (y
),
3467 SCM_CPLXP (y
) ? -SCM_IMAG (y
) : 0.0);
3469 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3471 return scm_makdbl (SCM_REALPART (x
) - scm_big2dbl (y
),
3472 SCM_CPLXP (x
) ? SCM_IMAG (x
) : 0.0);
3473 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3475 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3476 SCM_ASRTGO (SCM_NIMP (y
) && SCM_INEXP (y
), bady
);
3481 return scm_makdbl (SCM_REAL (x
) - SCM_REAL (y
),
3482 SCM_IMAG (x
) - SCM_IMAG (y
));
3484 return scm_makdbl (SCM_REAL (x
) - SCM_REALPART (y
), SCM_IMAG (x
));
3486 return scm_makdbl (SCM_REALPART (x
) - SCM_REALPART (y
),
3487 SCM_CPLXP (y
) ? - SCM_IMAG (y
) : 0.0);
3497 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3500 #ifndef SCM_DIGSTOOBIG
3501 long z
= scm_pseudolong (SCM_INUM (x
));
3502 return scm_addbig ((SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3503 (x
< 0) ? 0x0100 : 0,
3506 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3507 scm_longdigs (SCM_INUM (x
), zdigs
);
3508 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3512 if (!(SCM_INEXP (y
)))
3515 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3518 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
3521 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3524 return scm_makdbl (SCM_INUM (x
) - SCM_REALPART (y
),
3525 SCM_CPLXP (y
) ? -SCM_IMAG (y
) : 0.0);
3531 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
3532 g_difference
, x
, y
, SCM_ARG1
, s_difference
);
3535 x
= scm_copybig (x
, !SCM_BIGSIGN (x
));
3536 return (SCM_NUMDIGS (x
) * SCM_BITSPERDIG
/ SCM_CHAR_BIT
3538 ? scm_big2inum (x
, SCM_NUMDIGS (x
))
3543 #ifndef SCM_DIGSTOOBIG
3544 long z
= scm_pseudolong (SCM_INUM (y
));
3545 return scm_addbig (&z
, SCM_DIGSPERLONG
, (y
< 0) ? 0 : 0x0100, x
, 0);
3547 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3548 scm_longdigs (SCM_INUM (x
), zdigs
);
3549 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (y
< 0) ? 0 : 0x0100,
3553 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3554 return (SCM_NUMDIGS (x
) < SCM_NUMDIGS (y
)) ?
3555 scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
), SCM_BIGSIGN (x
),
3557 scm_addbig (SCM_BDIGITS (y
), SCM_NUMDIGS (y
), SCM_BIGSIGN (y
) ^ 0x0100,
3567 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3570 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3573 #ifndef SCM_DIGSTOOBIG
3574 long z
= scm_pseudolong (SCM_INUM (x
));
3575 return scm_addbig (&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3578 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3579 scm_longdigs (SCM_INUM (x
), zdigs
);
3580 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3586 SCM_GASSERT2 (SCM_INUMP (x
), g_difference
, x
, y
, SCM_ARG1
, s_difference
);
3592 SCM_GASSERT2 (SCM_INUMP (y
), g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3595 x
= SCM_INUM (x
) - SCM_INUM (y
);
3597 if (SCM_FIXABLE (x
))
3598 return SCM_MAKINUM (x
);
3600 return scm_long2big (x
);
3603 return scm_makdbl ((double) x
, 0.0);
3605 scm_num_overflow (s_difference
);
3606 return SCM_UNSPECIFIED
;
3614 SCM_GPROC1 (s_product
, "*", scm_tc7_asubr
, scm_product
, g_product
);
3624 return SCM_MAKINUM (1L);
3625 SCM_GASSERT1 (SCM_NUMBERP (x
), g_product
, x
, SCM_ARG1
, s_product
);
3636 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARG1
, s_product
);
3647 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3649 return scm_mulbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3650 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3651 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
));
3652 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3655 double bg
= scm_big2dbl (x
);
3656 return scm_makdbl (bg
* SCM_REALPART (y
),
3657 SCM_CPLXP (y
) ? bg
* SCM_IMAG (y
) : 0.0);
3660 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3662 SCM_ASRTGO (SCM_NIMP (x
) && SCM_INEXP (x
), badx2
);
3672 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3680 else if (!(SCM_INEXP (y
)))
3683 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARGn
, s_product
);
3686 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
3689 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARGn
, s_product
);
3695 return scm_makdbl (SCM_REAL (x
) * SCM_REAL (y
)
3696 - SCM_IMAG (x
) * SCM_IMAG (y
),
3697 SCM_REAL (x
) * SCM_IMAG (y
)
3698 + SCM_IMAG (x
) * SCM_REAL (y
));
3700 return scm_makdbl (SCM_REAL (x
) * SCM_REALPART (y
),
3701 SCM_IMAG (x
) * SCM_REALPART (y
));
3703 return scm_makdbl (SCM_REALPART (x
) * SCM_REALPART (y
),
3705 ? SCM_REALPART (x
) * SCM_IMAG (y
)
3711 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3717 if (SCM_MAKINUM (1L) == x
)
3720 #ifndef SCM_DIGSTOOBIG
3721 long z
= scm_pseudolong (SCM_INUM (x
));
3722 return scm_mulbig ((SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3723 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3724 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3726 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3727 scm_longdigs (SCM_INUM (x
), zdigs
);
3728 return scm_mulbig (zdigs
, SCM_DIGSPERLONG
,
3729 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3730 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3734 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3736 SCM_ASRTGO (SCM_NIMP (y
) && SCM_INEXP (y
), bady
);
3739 return scm_makdbl (SCM_INUM (x
) * SCM_REALPART (y
),
3740 SCM_CPLXP (y
) ? SCM_INUM (x
) * SCM_IMAG (y
) : 0.0);
3746 SCM_ASRTGO (SCM_NIMP (x
) && SCM_BIGP (x
), badx2
);
3754 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3755 return scm_mulbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3756 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3757 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
));
3761 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3764 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARGn
, s_product
);
3769 if (SCM_MAKINUM (1L) == x
)
3772 #ifndef SCM_DIGSTOOBIG
3773 long z
= scm_pseudolong (SCM_INUM (x
));
3774 return scm_mulbig (&z
, SCM_DIGSPERLONG
,
3775 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3776 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3778 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3779 scm_longdigs (SCM_INUM (x
), zdigs
);
3780 return scm_mulbig (zdigs
, SCM_DIGSPERLONG
,
3781 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3782 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3787 SCM_ASRTGO (SCM_INUMP (x
), badx2
);
3788 SCM_GASSERT (SCM_INUMP (y
), g_product
, x
, y
, SCM_ARGn
, s_product
);
3798 y
= SCM_MAKINUM (k
);
3799 if (k
!= SCM_INUM (y
) || k
/ i
!= j
)
3802 int sgn
= (i
< 0) ^ (j
< 0);
3803 #ifndef SCM_DIGSTOOBIG
3804 i
= scm_pseudolong (i
);
3805 j
= scm_pseudolong (j
);
3806 return scm_mulbig ((SCM_BIGDIG
*) & i
, SCM_DIGSPERLONG
,
3807 (SCM_BIGDIG
*) & j
, SCM_DIGSPERLONG
, sgn
);
3808 #else /* SCM_DIGSTOOBIG */
3809 SCM_BIGDIG idigs
[SCM_DIGSPERLONG
];
3810 SCM_BIGDIG jdigs
[SCM_DIGSPERLONG
];
3811 scm_longdigs (i
, idigs
);
3812 scm_longdigs (j
, jdigs
);
3813 return scm_mulbig (idigs
, SCM_DIGSPERLONG
,
3814 jdigs
, SCM_DIGSPERLONG
,
3820 return scm_makdbl (((double) i
) * ((double) j
), 0.0);
3822 scm_num_overflow (s_product
);
3832 scm_num2dbl (a
, why
)
3837 return (double) SCM_INUM (a
);
3839 SCM_ASSERT (SCM_NIMP (a
), a
, "wrong type argument", why
);
3841 return (SCM_REALPART (a
));
3844 return scm_big2dbl (a
);
3846 SCM_ASSERT (0, a
, "wrong type argument", why
);
3847 return SCM_UNSPECIFIED
;
3851 SCM_GPROC1 (s_divide
, "/", scm_tc7_asubr
, scm_divide
, g_divide
);
3862 if (!(SCM_NIMP (x
)))
3866 SCM_GASSERT0 (!SCM_UNBNDP (x
),
3867 g_divide
, scm_makfrom0str (s_divide
), SCM_WNA
, 0);
3869 SCM_WTA_DISPATCH_1 (g_divide
, x
, SCM_ARG1
, s_divide
);
3874 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARG1
, s_divide
);
3881 return scm_makdbl (1.0 / scm_big2dbl (x
), 0.0);
3883 SCM_ASRTGO (SCM_INEXP (x
), badx
);
3885 return scm_makdbl (1.0 / SCM_REALPART (x
), 0.0);
3889 return scm_makdbl (r
/ d
, -i
/ d
);
3898 #ifndef SCM_RECKLESS
3900 scm_num_overflow (s_divide
);
3908 SCM w
= scm_copybig (x
, SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0));
3909 return (scm_divbigdig (SCM_BDIGITS (w
), SCM_NUMDIGS (w
),
3911 ? scm_makdbl (scm_big2dbl (x
) / SCM_INUM (y
), 0.0)
3914 #ifndef SCM_DIGSTOOBIG
3915 z
= scm_pseudolong (z
);
3916 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3917 (SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3918 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
3921 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3922 scm_longdigs (z
, zdigs
);
3923 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3924 zdigs
, SCM_DIGSPERLONG
,
3925 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
3928 return z
? z
: scm_makdbl (scm_big2dbl (x
) / SCM_INUM (y
), 0.0);
3930 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3933 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3934 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3935 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
), 3);
3936 return z
? z
: scm_makdbl (scm_big2dbl (x
) / scm_big2dbl (y
),
3939 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3941 return scm_makdbl (scm_big2dbl (x
) / SCM_REALPART (y
), 0.0);
3942 a
= scm_big2dbl (x
);
3946 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3953 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3956 d
= scm_big2dbl (y
);
3959 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3961 SCM_ASRTGO (SCM_NIMP (y
) && SCM_INEXP (y
), bady
);
3965 d
= SCM_REALPART (y
);
3967 return scm_makdbl (SCM_REALPART (x
) / d
,
3968 SCM_CPLXP (x
) ? SCM_IMAG (x
) / d
: 0.0);
3970 a
= SCM_REALPART (x
);
3976 return scm_makdbl ((a
* r
+ SCM_IMAG (x
) * i
) / d
,
3977 (SCM_IMAG (x
) * r
- a
* i
) / d
);
3981 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
3983 return scm_makdbl (1.0 / ((double) SCM_INUM (x
)), 0.0);
3988 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3990 return scm_makdbl (SCM_INUM (x
) / scm_big2dbl (y
), 0.0);
3991 if (!(SCM_INEXP (y
)))
3994 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARGn
, s_divide
);
3997 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
4000 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARGn
, s_divide
);
4004 return scm_makdbl (SCM_INUM (x
) / SCM_REALPART (y
), 0.0);
4010 return scm_makdbl ((a
* r
) / d
, (-a
* i
) / d
);
4017 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
4018 g_divide
, x
, y
, SCM_ARG1
, s_divide
);
4032 SCM w
= scm_copybig (x
, SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0));
4033 if (scm_divbigdig (SCM_BDIGITS (w
), SCM_NUMDIGS (w
),
4038 #ifndef SCM_DIGSTOOBIG
4039 z
= scm_pseudolong (z
);
4040 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
4041 &z
, SCM_DIGSPERLONG
,
4042 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
4045 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
4046 scm_longdigs (z
, zdigs
);
4047 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
4048 zdigs
, SCM_DIGSPERLONG
,
4049 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
4055 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
4056 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
4057 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
4058 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
), 3);
4066 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
4072 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
4075 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARGn
, s_divide
);
4080 SCM_GASSERT2 (SCM_INUMP (x
), g_divide
, x
, y
, SCM_ARG1
, s_divide
);
4083 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
4087 SCM_GASSERT2 (SCM_INUMP (y
), g_divide
, x
, y
, SCM_ARGn
, s_divide
);
4091 long z
= SCM_INUM (y
);
4092 if ((0 == z
) || SCM_INUM (x
) % z
)
4094 z
= SCM_INUM (x
) / z
;
4095 if (SCM_FIXABLE (z
))
4096 return SCM_MAKINUM (z
);
4098 return scm_long2big (z
);
4102 return scm_makdbl (((double) SCM_INUM (x
)) / ((double) SCM_INUM (y
)), 0.0);
4105 scm_num_overflow (s_divide
);
4106 return SCM_UNSPECIFIED
;
4115 SCM_GPROC1 (s_asinh
, "$asinh", scm_tc7_cxr
, (SCM (*)()) scm_asinh
, g_asinh
);
4121 return log (x
+ sqrt (x
* x
+ 1));
4127 SCM_GPROC1 (s_acosh
, "$acosh", scm_tc7_cxr
, (SCM (*)()) scm_acosh
, g_acosh
);
4133 return log (x
+ sqrt (x
* x
- 1));
4139 SCM_GPROC1 (s_atanh
, "$atanh", scm_tc7_cxr
, (SCM (*)()) scm_atanh
, g_atanh
);
4145 return 0.5 * log ((1 + x
) / (1 - x
));
4151 SCM_GPROC1 (s_truncate
, "truncate", scm_tc7_cxr
, (SCM (*)()) scm_truncate
, g_truncate
);
4164 SCM_GPROC1 (s_round
, "round", scm_tc7_cxr
, (SCM (*)()) scm_round
, g_round
);
4170 double plus_half
= x
+ 0.5;
4171 double result
= floor (plus_half
);
4172 /* Adjust so that the scm_round is towards even. */
4173 return (plus_half
== result
&& plus_half
/ 2 != floor (plus_half
/ 2))
4174 ? result
- 1 : result
;
4179 SCM_GPROC1 (s_exact_to_inexact
, "exact->inexact", scm_tc7_cxr
, (SCM (*)()) scm_exact_to_inexact
, g_exact_to_inexact
);
4182 scm_exact_to_inexact (z
)
4189 SCM_GPROC1 (s_i_floor
, "floor", scm_tc7_cxr
, (SCM (*)()) floor
, g_i_floor
);
4190 SCM_GPROC1 (s_i_ceil
, "ceiling", scm_tc7_cxr
, (SCM (*)()) ceil
, g_i_ceil
);
4191 SCM_GPROC1 (s_i_sqrt
, "$sqrt", scm_tc7_cxr
, (SCM (*)()) sqrt
, g_i_sqrt
);
4192 SCM_GPROC1 (s_i_abs
, "$abs", scm_tc7_cxr
, (SCM (*)()) fabs
, g_i_abs
);
4193 SCM_GPROC1 (s_i_exp
, "$exp", scm_tc7_cxr
, (SCM (*)()) exp
, g_i_exp
);
4194 SCM_GPROC1 (s_i_log
, "$log", scm_tc7_cxr
, (SCM (*)()) log
, g_i_log
);
4195 SCM_GPROC1 (s_i_sin
, "$sin", scm_tc7_cxr
, (SCM (*)()) sin
, g_i_sin
);
4196 SCM_GPROC1 (s_i_cos
, "$cos", scm_tc7_cxr
, (SCM (*)()) cos
, g_i_cos
);
4197 SCM_GPROC1 (s_i_tan
, "$tan", scm_tc7_cxr
, (SCM (*)()) tan
, g_i_tan
);
4198 SCM_GPROC1 (s_i_asin
, "$asin", scm_tc7_cxr
, (SCM (*)()) asin
, g_i_asin
);
4199 SCM_GPROC1 (s_i_acos
, "$acos", scm_tc7_cxr
, (SCM (*)()) acos
, g_i_acos
);
4200 SCM_GPROC1 (s_i_atan
, "$atan", scm_tc7_cxr
, (SCM (*)()) atan
, g_i_atan
);
4201 SCM_GPROC1 (s_i_sinh
, "$sinh", scm_tc7_cxr
, (SCM (*)()) sinh
, g_i_sinh
);
4202 SCM_GPROC1 (s_i_cosh
, "$cosh", scm_tc7_cxr
, (SCM (*)()) cosh
, g_i_cosh
);
4203 SCM_GPROC1 (s_i_tanh
, "$tanh", scm_tc7_cxr
, (SCM (*)()) tanh
, g_i_tanh
);
4210 static void scm_two_doubles (SCM z1
,
4212 const char *sstring
,
4216 scm_two_doubles (z1
, z2
, sstring
, xy
)
4218 const char *sstring
;
4222 xy
->x
= SCM_INUM (z1
);
4226 SCM_ASRTGO (SCM_NIMP (z1
), badz1
);
4228 xy
->x
= scm_big2dbl (z1
);
4231 #ifndef SCM_RECKLESS
4232 if (!(SCM_REALP (z1
)))
4233 badz1
:scm_wta (z1
, (char *) SCM_ARG1
, sstring
);
4235 xy
->x
= SCM_REALPART (z1
);
4239 SCM_ASSERT (SCM_NIMP (z1
) && SCM_REALP (z1
), z1
, SCM_ARG1
, sstring
);
4240 xy
->x
= SCM_REALPART (z1
);
4245 xy
->y
= SCM_INUM (z2
);
4249 SCM_ASRTGO (SCM_NIMP (z2
), badz2
);
4251 xy
->y
= scm_big2dbl (z2
);
4254 #ifndef SCM_RECKLESS
4255 if (!(SCM_REALP (z2
)))
4256 badz2
:scm_wta (z2
, (char *) SCM_ARG2
, sstring
);
4258 xy
->y
= SCM_REALPART (z2
);
4262 SCM_ASSERT (SCM_NIMP (z2
) && SCM_REALP (z2
), z2
, SCM_ARG2
, sstring
);
4263 xy
->y
= SCM_REALPART (z2
);
4272 SCM_PROC (s_sys_expt
, "$expt", 2, 0, 0, scm_sys_expt
);
4275 scm_sys_expt (z1
, z2
)
4280 scm_two_doubles (z1
, z2
, s_sys_expt
, &xy
);
4281 return scm_makdbl (pow (xy
.x
, xy
.y
), 0.0);
4286 SCM_PROC (s_sys_atan2
, "$atan2", 2, 0, 0, scm_sys_atan2
);
4289 scm_sys_atan2 (z1
, z2
)
4294 scm_two_doubles (z1
, z2
, s_sys_atan2
, &xy
);
4295 return scm_makdbl (atan2 (xy
.x
, xy
.y
), 0.0);
4300 SCM_PROC (s_make_rectangular
, "make-rectangular", 2, 0, 0, scm_make_rectangular
);
4303 scm_make_rectangular (z1
, z2
)
4308 scm_two_doubles (z1
, z2
, s_make_rectangular
, &xy
);
4309 return scm_makdbl (xy
.x
, xy
.y
);
4314 SCM_PROC (s_make_polar
, "make-polar", 2, 0, 0, scm_make_polar
);
4317 scm_make_polar (z1
, z2
)
4322 scm_two_doubles (z1
, z2
, s_make_polar
, &xy
);
4323 return scm_makdbl (xy
.x
* cos (xy
.y
), xy
.x
* sin (xy
.y
));
4329 SCM_GPROC (s_real_part
, "real-part", 1, 0, 0, scm_real_part
, g_real_part
);
4338 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4341 if (!(SCM_INEXP (z
)))
4344 SCM_WTA_DISPATCH_1 (g_real_part
, z
, SCM_ARG1
, s_real_part
);
4347 SCM_GASSERT1 (SCM_NIMP (z
) && SCM_INEXP (z
),
4348 g_real_part
, z
, SCM_ARG1
, s_real_part
);
4351 return scm_makdbl (SCM_REAL (z
), 0.0);
4358 SCM_GPROC (s_imag_part
, "imag-part", 1, 0, 0, scm_imag_part
, g_imag_part
);
4367 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4370 if (!(SCM_INEXP (z
)))
4373 SCM_WTA_DISPATCH_1 (g_imag_part
, z
, SCM_ARG1
, s_imag_part
);
4376 SCM_GASSERT1 (SCM_NIMP (z
) && SCM_INEXP (z
),
4377 g_imag_part
, z
, SCM_ARG1
, s_imag_part
);
4380 return scm_makdbl (SCM_IMAG (z
), 0.0);
4386 SCM_GPROC (s_magnitude
, "magnitude", 1, 0, 0, scm_magnitude
, g_magnitude
);
4395 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4398 if (!(SCM_INEXP (z
)))
4401 SCM_WTA_DISPATCH_1 (g_magnitude
, z
, SCM_ARG1
, s_magnitude
);
4404 SCM_GASSERT1 (SCM_NIMP (z
) && SCM_INEXP (z
),
4405 g_magnitude
, z
, SCM_ARG1
, s_magnitude
);
4409 double i
= SCM_IMAG (z
), r
= SCM_REAL (z
);
4410 return scm_makdbl (sqrt (i
* i
+ r
* r
), 0.0);
4412 return scm_makdbl (fabs (SCM_REALPART (z
)), 0.0);
4418 SCM_GPROC (s_angle
, "angle", 1, 0, 0, scm_angle
, g_angle
);
4427 x
= (z
>= SCM_INUM0
) ? 1.0 : -1.0;
4431 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4434 x
= (SCM_TYP16 (z
) == scm_tc16_bigpos
) ? 1.0 : -1.0;
4437 if (!(SCM_INEXP (z
)))
4440 SCM_WTA_DISPATCH_1 (g_angle
, z
, SCM_ARG1
, s_angle
);
4443 SCM_GASSERT1 (SCM_NIMP (z
) && SCM_INEXP (z
), g_angle
, z
, SCM_ARG1
, s_angle
);
4447 x
= SCM_REALPART (z
);
4453 return scm_makdbl (atan2 (y
, x
), 0.0);
4457 SCM_PROC (s_inexact_to_exact
, "inexact->exact", 1, 0, 0, scm_inexact_to_exact
);
4460 scm_inexact_to_exact (z
)
4466 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4469 #ifndef SCM_RECKLESS
4470 if (!(SCM_REALP (z
)))
4473 scm_wta (z
, (char *) SCM_ARG1
, s_inexact_to_exact
);
4477 SCM_ASSERT (SCM_NIMP (z
) && SCM_REALP (z
), z
, SCM_ARG1
, s_inexact_to_exact
);
4481 double u
= floor (SCM_REALPART (z
) + 0.5);
4482 if ((u
<= SCM_MOST_POSITIVE_FIXNUM
) && (-u
<= -SCM_MOST_NEGATIVE_FIXNUM
))
4484 /* Negation is a workaround for HP700 cc bug */
4485 SCM ans
= SCM_MAKINUM ((long) u
);
4486 if (SCM_INUM (ans
) == (long) u
)
4489 SCM_ASRTGO (isfinite (u
), badz
); /* problem? */
4490 return scm_dbl2big (u
);
4493 return SCM_MAKINUM ((long) floor (SCM_REALPART (z
) + 0.5));
4499 #else /* ~SCM_FLOATS */
4500 SCM_GPROC (s_trunc
, "truncate", 1, 0, 0, scm_trunc
, g_trunc
);
4506 SCM_GASSERT2 (SCM_INUMP (x
), g_trunc
, x
, y
, SCM_ARG1
, s_truncate
);
4512 #endif /* SCM_FLOATS */
4516 /* d must be integer */
4526 double u
= (d
< 0) ? -d
: d
;
4527 while (0 != floor (u
))
4532 ans
= scm_mkbig (i
, d
< 0);
4533 digits
= SCM_BDIGITS (ans
);
4541 #ifndef SCM_RECKLESS
4543 scm_num_overflow ("dbl2big");
4555 scm_sizet i
= SCM_NUMDIGS (b
);
4556 SCM_BIGDIG
*digits
= SCM_BDIGITS (b
);
4558 ans
= digits
[i
] + SCM_BIGRAD
* ans
;
4559 if (scm_tc16_bigneg
== SCM_TYP16 (b
))
4571 if (!SCM_FIXABLE (sl
))
4574 return scm_long2big (sl
);
4577 return scm_makdbl ((double) sl
, 0.0);
4583 return SCM_MAKINUM (sl
);
4590 scm_long_long2num (sl
)
4593 if (!SCM_FIXABLE (sl
))
4596 return scm_long_long2big (sl
);
4599 return scm_makdbl ((double) sl
, 0.0);
4605 return SCM_MAKINUM (sl
);
4615 if (!SCM_POSFIXABLE (sl
))
4618 return scm_ulong2big (sl
);
4621 return scm_makdbl ((double) sl
, 0.0);
4627 return SCM_MAKINUM (sl
);
4632 scm_num2long (num
, pos
, s_caller
)
4635 const char *s_caller
;
4638 if (SCM_INUMP (num
))
4640 res
= SCM_INUM (num
);
4643 SCM_ASRTGO (SCM_NIMP (num
), errout
);
4645 if (SCM_REALP (num
))
4647 double u
= SCM_REALPART (num
);
4649 if ((double) res
== u
)
4662 for (l
= SCM_NUMDIGS (num
); l
--;)
4664 res
= SCM_BIGUP (res
) + SCM_BDIGITS (num
)[l
];
4669 if (SCM_TYP16 (num
) == scm_tc16_bigpos
)
4676 scm_wta (num
, pos
, s_caller
);
4677 return SCM_UNSPECIFIED
;
4685 scm_num2long_long (num
, pos
, s_caller
)
4688 const char *s_caller
;
4691 if (SCM_INUMP (num
))
4693 res
= SCM_INUM ((long_long
) num
);
4696 SCM_ASRTGO (SCM_NIMP (num
), errout
);
4698 if (SCM_REALP (num
))
4700 double u
= SCM_REALPART (num
);
4701 if (((SCM_MOST_NEGATIVE_FIXNUM
* 4) <= u
)
4702 && (u
<= (SCM_MOST_POSITIVE_FIXNUM
* 4 + 3)))
4712 scm_sizet l
= SCM_NUMDIGS (num
);
4713 SCM_ASRTGO (SCM_DIGSPERLONGLONG
>= l
, errout
);
4716 res
= SCM_LONGLONGBIGUP (res
) + SCM_BDIGITS (num
)[l
];
4721 scm_wta (num
, pos
, s_caller
);
4722 return SCM_UNSPECIFIED
;
4729 scm_num2ulong (num
, pos
, s_caller
)
4732 const char *s_caller
;
4735 if (SCM_INUMP (num
))
4737 res
= SCM_INUM ((unsigned long) num
);
4740 SCM_ASRTGO (SCM_NIMP (num
), errout
);
4742 if (SCM_REALP (num
))
4744 double u
= SCM_REALPART (num
);
4745 if ((0 <= u
) && (u
<= (unsigned long) ~0L))
4755 unsigned long oldres
;
4759 for (l
= SCM_NUMDIGS (num
); l
--;)
4761 res
= SCM_BIGUP (res
) + SCM_BDIGITS (num
)[l
];
4770 scm_wta (num
, pos
, s_caller
);
4771 return SCM_UNSPECIFIED
;
4777 static void add1
SCM_P ((double f
, double *fsum
));
4792 scm_add_feature("complex");
4794 scm_add_feature("inexact");
4796 SCM_NEWSMOB(scm_flo0
,scm_tc_flo
,NULL
);
4798 SCM_NEWSMOB(scm_flo0
,scm_tc_dblr
,scm_must_malloc (1L * sizeof (double), "real"));
4799 SCM_REAL (scm_flo0
) = 0.0;
4802 scm_dblprec
= (DBL_DIG
> 20) ? 20 : DBL_DIG
;
4804 { /* determine floating point precision */
4806 double fsum
= 1.0 + f
;
4810 if (++scm_dblprec
> 20)
4814 scm_dblprec
= scm_dblprec
- 1;
4816 #endif /* DBL_DIG */
4818 #include "numbers.x"