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);
2453 SCM_ASSERT (SCM_INUMP (radix
), radix
, SCM_ARG2
, s_string_to_number
);
2454 SCM_ASSERT (SCM_NIMP (str
) && SCM_ROSTRINGP (str
),
2455 str
, SCM_ARG1
, s_string_to_number
);
2456 answer
= scm_istring2number (SCM_ROCHARS (str
),
2459 return scm_return_first (answer
, str
);
2461 /*** END strs->nums ***/
2471 if ((y
== 0.0) && (x
== 0.0))
2478 #ifndef SCM_SINGLESONLY
2479 if ((-FLTMAX
< x
) && (x
< FLTMAX
) && (fx
== x
))
2482 SCM_NEWSMOB(z
,scm_tc_flo
,NULL
);
2487 #endif /* def SCM_SINGLES */
2488 SCM_NEWSMOB(z
,scm_tc_dblr
,scm_must_malloc (1L * sizeof (double), "real"));
2492 SCM_NEWSMOB(z
,scm_tc_dblc
,scm_must_malloc (2L * sizeof (double), "comkplex"));
2509 if (0 == scm_bigcomp (x
, y
))
2523 if (SCM_REALPART (x
) != SCM_REALPART (y
))
2525 if (!(SCM_CPLXP (x
) && (SCM_IMAG (x
) != SCM_IMAG (y
))))
2534 SCM_PROC (s_number_p
, "number?", 1, 0, 0, scm_number_p
);
2535 SCM_PROC (s_complex_p
, "complex?", 1, 0, 0, scm_number_p
);
2544 if (SCM_NIMP (x
) && SCM_NUMP (x
))
2548 if (SCM_NIMP (x
) && SCM_NUMP (x
))
2558 SCM_PROC (s_real_p
, "real?", 1, 0, 0, scm_real_p
);
2559 SCM_PROC (s_rational_p
, "rational?", 1, 0, 0, scm_real_p
);
2580 SCM_PROC (s_int_p
, "integer?", 1, 0, 0, scm_integer_p
);
2599 r
= SCM_REALPART (x
);
2607 #endif /* SCM_FLOATS */
2609 SCM_PROC (s_inexact_p
, "inexact?", 1, 0, 0, scm_inexact_p
);
2616 if (SCM_NIMP (x
) && SCM_INEXP (x
))
2625 SCM_GPROC1 (s_eq_p
, "=", scm_tc7_rpsubr
, scm_num_eq_p
, g_eq_p
);
2637 if (!(SCM_NIMP (x
)))
2640 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2646 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2648 return (0 == scm_bigcomp (x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2649 SCM_ASRTGO (SCM_INEXP (y
), bady
);
2651 return ((SCM_REALP (y
) && (scm_big2dbl (x
) == SCM_REALPART (y
)))
2655 SCM_ASRTGO (SCM_INEXP (x
), badx
);
2657 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_INEXP (x
),
2658 g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2668 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2676 SCM_ASRTGO (SCM_INEXP (y
), bady
);
2678 SCM_ASRTGO (SCM_NIMP (y
) && SCM_INEXP (y
), bady
);
2680 if (SCM_REALPART (x
) != SCM_REALPART (y
))
2683 return ((SCM_CPLXP (y
) && (SCM_IMAG (x
) == SCM_IMAG (y
)))
2686 return SCM_CPLXP (y
) ? SCM_BOOL_F
: SCM_BOOL_T
;
2691 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2694 if (!(SCM_INEXP (y
)))
2697 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2700 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
2703 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2707 return ((SCM_REALP (y
) && (((double) SCM_INUM (x
)) == SCM_REALPART (y
)))
2715 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
2716 g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2719 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
2720 return (0 == scm_bigcomp (x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2724 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
2727 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2732 SCM_GASSERT2 (SCM_INUMP (x
), g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2733 SCM_GASSERT2 (SCM_INUMP (y
), g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2736 return ((long) x
== (long) y
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2741 SCM_GPROC1 (s_less_p
, "<", scm_tc7_rpsubr
, scm_less_p
, g_less_p
);
2752 if (!(SCM_NIMP (x
)))
2755 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2760 return SCM_BIGSIGN (x
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2761 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2763 return (1 == scm_bigcomp (x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2764 SCM_ASRTGO (SCM_REALP (y
), bady
);
2765 return ((scm_big2dbl (x
) < SCM_REALPART (y
))
2769 SCM_ASRTGO (SCM_REALP (x
), badx
);
2771 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_REALP (x
),
2772 g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2775 return ((SCM_REALPART (x
) < ((double) SCM_INUM (y
)))
2779 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2781 return (SCM_REALPART (x
) < scm_big2dbl (y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2782 SCM_ASRTGO (SCM_REALP (y
), bady
);
2784 SCM_ASRTGO (SCM_NIMP (y
) && SCM_REALP (y
), bady
);
2786 return (SCM_REALPART (x
) < SCM_REALPART (y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2791 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2793 return SCM_BIGSIGN (y
) ? SCM_BOOL_F
: SCM_BOOL_T
;
2794 if (!(SCM_REALP (y
)))
2797 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2800 if (!(SCM_NIMP (y
) && SCM_REALP (y
)))
2803 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2806 return ((((double) SCM_INUM (x
)) < SCM_REALPART (y
))
2814 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
2815 g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2817 return SCM_BIGSIGN (x
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2818 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
2819 return (1 == scm_bigcomp (x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2823 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
2826 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2828 return SCM_BIGSIGN (y
) ? SCM_BOOL_F
: SCM_BOOL_T
;
2831 SCM_GASSERT2 (SCM_INUMP (x
), g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2832 SCM_GASSERT2 (SCM_INUMP (y
), g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2835 return ((long) x
< (long) y
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2839 SCM_PROC1 (s_gr_p
, ">", scm_tc7_rpsubr
, scm_gr_p
);
2846 return scm_less_p (y
, x
);
2851 SCM_PROC1 (s_leq_p
, "<=", scm_tc7_rpsubr
, scm_leq_p
);
2858 return SCM_BOOL_NOT (scm_less_p (y
, x
));
2863 SCM_PROC1 (s_geq_p
, ">=", scm_tc7_rpsubr
, scm_geq_p
);
2870 return SCM_BOOL_NOT (scm_less_p (x
, y
));
2875 SCM_GPROC (s_zero_p
, "zero?", 1, 0, 0, scm_zero_p
, g_zero_p
);
2885 SCM_ASRTGO (SCM_NIMP (z
), badz
);
2888 if (!(SCM_INEXP (z
)))
2891 SCM_WTA_DISPATCH_1 (g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2894 SCM_GASSERT1 (SCM_NIMP (z
) && SCM_INEXP (z
),
2895 g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2897 return (z
== scm_flo0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2903 SCM_GASSERT1 (SCM_NIMP (z
) && SCM_BIGP (z
),
2904 g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2908 SCM_GASSERT1 (SCM_INUMP (z
), g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2911 return (z
== SCM_INUM0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2916 SCM_GPROC (s_positive_p
, "positive?", 1, 0, 0, scm_positive_p
, g_positive_p
);
2926 SCM_ASRTGO (SCM_NIMP (x
), badx
);
2928 return SCM_TYP16 (x
) == scm_tc16_bigpos
? SCM_BOOL_T
: SCM_BOOL_F
;
2929 if (!(SCM_REALP (x
)))
2932 SCM_WTA_DISPATCH_1 (g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2935 SCM_GASSERT1 (SCM_NIMP (x
) && SCM_REALP (x
),
2936 g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2938 return (SCM_REALPART (x
) > 0.0) ? SCM_BOOL_T
: SCM_BOOL_F
;
2944 SCM_GASSERT1 (SCM_NIMP (x
) && SCM_BIGP (x
),
2945 g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2946 return SCM_TYP16 (x
) == scm_tc16_bigpos
? SCM_BOOL_T
: SCM_BOOL_F
;
2949 SCM_GASSERT1 (SCM_INUMP (x
), g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2952 return (x
> SCM_INUM0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2957 SCM_GPROC (s_negative_p
, "negative?", 1, 0, 0, scm_negative_p
, g_negative_p
);
2967 SCM_ASRTGO (SCM_NIMP (x
), badx
);
2969 return SCM_TYP16 (x
) == scm_tc16_bigpos
? SCM_BOOL_F
: SCM_BOOL_T
;
2970 if (!(SCM_REALP (x
)))
2973 SCM_WTA_DISPATCH_1 (g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2976 SCM_GASSERT1 (SCM_NIMP (x
) && SCM_REALP (x
),
2977 g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2979 return (SCM_REALPART (x
) < 0.0) ? SCM_BOOL_T
: SCM_BOOL_F
;
2985 SCM_GASSERT1 (SCM_NIMP (x
) && SCM_BIGP (x
),
2986 g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2987 return (SCM_TYP16 (x
) == scm_tc16_bigneg
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2990 SCM_GASSERT1 (SCM_INUMP (x
), g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2993 return (x
< SCM_INUM0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2997 SCM_GPROC1 (s_max
, "max", scm_tc7_asubr
, scm_max
, g_max
);
3009 SCM_GASSERT0 (!SCM_UNBNDP (x
),
3010 g_max
, scm_makfrom0str (s_max
), SCM_WNA
, 0);
3011 SCM_GASSERT1 (SCM_NUMBERP (x
), g_max
, x
, SCM_ARG1
, s_max
);
3021 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARG1
, s_max
);
3026 return SCM_BIGSIGN (x
) ? y
: x
;
3027 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3029 return (1 == scm_bigcomp (x
, y
)) ? y
: x
;
3030 SCM_ASRTGO (SCM_REALP (y
), bady
);
3031 z
= scm_big2dbl (x
);
3032 return (z
< SCM_REALPART (y
)) ? y
: scm_makdbl (z
, 0.0);
3034 SCM_ASRTGO (SCM_REALP (x
), badx2
);
3036 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_REALP (x
),
3037 g_max
, x
, y
, SCM_ARG1
, s_max
);
3040 return ((SCM_REALPART (x
) < (z
= SCM_INUM (y
)))
3041 ? scm_makdbl (z
, 0.0)
3044 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3046 return ((SCM_REALPART (x
) < (z
= scm_big2dbl (y
)))
3047 ? scm_makdbl (z
, 0.0)
3049 SCM_ASRTGO (SCM_REALP (y
), bady
);
3051 SCM_ASRTGO (SCM_NIMP (y
) && SCM_REALP (y
), bady
);
3053 return (SCM_REALPART (x
) < SCM_REALPART (y
)) ? y
: x
;
3058 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3060 return SCM_BIGSIGN (y
) ? x
: y
;
3061 if (!(SCM_REALP (y
)))
3064 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARGn
, s_max
);
3067 if (!(SCM_NIMP (y
) && SCM_REALP (y
)))
3070 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARGn
, s_max
);
3073 return (((z
= SCM_INUM (x
)) < SCM_REALPART (y
))
3075 : scm_makdbl (z
, 0.0));
3081 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
3082 g_max
, x
, y
, SCM_ARG1
, s_max
);
3084 return SCM_BIGSIGN (x
) ? y
: x
;
3085 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3086 return (1 == scm_bigcomp (x
, y
)) ? y
: x
;
3090 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3093 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARGn
, s_max
);
3095 return SCM_BIGSIGN (y
) ? x
: y
;
3098 SCM_GASSERT2 (SCM_INUMP (x
), g_max
, x
, y
, SCM_ARG1
, s_max
);
3099 SCM_GASSERT2 (SCM_INUMP (y
), g_max
, x
, y
, SCM_ARGn
, s_max
);
3102 return ((long) x
< (long) y
) ? y
: x
;
3108 SCM_GPROC1 (s_min
, "min", scm_tc7_asubr
, scm_min
, g_min
);
3120 SCM_GASSERT0 (!SCM_UNBNDP (x
),
3121 g_min
, scm_makfrom0str (s_min
), SCM_WNA
, 0);
3122 SCM_GASSERT1 (SCM_NUMBERP (x
), g_min
, x
, SCM_ARG1
, s_min
);
3129 if (!(SCM_NIMP (x
)))
3132 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARG1
, s_min
);
3137 return SCM_BIGSIGN (x
) ? x
: y
;
3138 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3140 return (-1 == scm_bigcomp (x
, y
)) ? y
: x
;
3141 SCM_ASRTGO (SCM_REALP (y
), bady
);
3142 z
= scm_big2dbl (x
);
3143 return (z
> SCM_REALPART (y
)) ? y
: scm_makdbl (z
, 0.0);
3145 SCM_ASRTGO (SCM_REALP (x
), badx2
);
3147 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_REALP (x
),
3148 g_min
, x
, y
, SCM_ARG1
, s_min
);
3151 return ((SCM_REALPART (x
) > (z
= SCM_INUM (y
)))
3152 ? scm_makdbl (z
, 0.0)
3155 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3157 return ((SCM_REALPART (x
) > (z
= scm_big2dbl (y
)))
3158 ? scm_makdbl (z
, 0.0)
3160 SCM_ASRTGO (SCM_REALP (y
), bady
);
3162 SCM_ASRTGO (SCM_NIMP (y
) && SCM_REALP (y
), bady
);
3164 return (SCM_REALPART (x
) > SCM_REALPART (y
)) ? y
: x
;
3169 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3171 return SCM_BIGSIGN (y
) ? y
: x
;
3172 if (!(SCM_REALP (y
)))
3175 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARGn
, s_min
);
3178 if (!(SCM_NIMP (y
) && SCM_REALP (y
)))
3181 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARGn
, s_min
);
3184 return (((z
= SCM_INUM (x
)) > SCM_REALPART (y
))
3186 : scm_makdbl (z
, 0.0));
3192 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
3193 g_min
, x
, y
, SCM_ARG1
, s_min
);
3195 return SCM_BIGSIGN (x
) ? x
: y
;
3196 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3197 return (-1 == scm_bigcomp (x
, y
)) ? y
: x
;
3201 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3204 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARGn
, s_min
);
3206 return SCM_BIGSIGN (y
) ? y
: x
;
3209 SCM_GASSERT2 (SCM_INUMP (x
), g_min
, x
, y
, SCM_ARG1
, s_min
);
3210 SCM_GASSERT2 (SCM_INUMP (y
), g_min
, x
, y
, SCM_ARGn
, s_min
);
3213 return ((long) x
> (long) y
) ? y
: x
;
3219 SCM_GPROC1 (s_sum
, "+", scm_tc7_asubr
, scm_sum
, g_sum
);
3230 SCM_GASSERT1 (SCM_NUMBERP (x
), g_sum
, x
, SCM_ARG1
, s_sum
);
3241 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARG1
, s_sum
);
3252 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3255 if (SCM_NUMDIGS (x
) > SCM_NUMDIGS (y
))
3261 return scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3265 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3267 return scm_makdbl (scm_big2dbl (x
) + SCM_REALPART (y
),
3268 SCM_CPLXP (y
) ? SCM_IMAG (y
) : 0.0);
3270 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3272 SCM_ASRTGO (SCM_NIMP (x
) && SCM_INEXP (x
), badx2
);
3282 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3290 else if (!(SCM_INEXP (y
)))
3293 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3296 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
3299 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3308 return scm_makdbl (SCM_REALPART (x
) + SCM_REALPART (y
), i
);
3314 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3319 #ifndef SCM_DIGSTOOBIG
3320 long z
= scm_pseudolong (SCM_INUM (x
));
3321 return scm_addbig ((SCM_BIGDIG
*) & z
,
3323 (x
< 0) ? 0x0100 : 0,
3326 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3327 scm_longdigs (SCM_INUM (x
), zdigs
);
3328 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3333 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3335 SCM_ASRTGO (SCM_NIMP (y
) && SCM_INEXP (y
), bady
);
3338 return scm_makdbl (SCM_INUM (x
) + SCM_REALPART (y
),
3339 SCM_CPLXP (y
) ? SCM_IMAG (y
) : 0.0);
3346 SCM_ASRTGO (SCM_NIMP (x
) && SCM_BIGP (x
), badx2
);
3354 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3355 if (SCM_NUMDIGS (x
) > SCM_NUMDIGS (y
))
3361 return scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
), SCM_BIGSIGN (x
),
3366 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3369 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3373 #ifndef SCM_DIGSTOOBIG
3374 long z
= scm_pseudolong (SCM_INUM (x
));
3375 return scm_addbig (&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
3377 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3378 scm_longdigs (SCM_INUM (x
), zdigs
);
3379 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
3384 SCM_ASRTGO (SCM_INUMP (x
), badx2
);
3385 SCM_GASSERT2 (SCM_INUMP (y
), g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3388 x
= SCM_INUM (x
) + SCM_INUM (y
);
3389 if (SCM_FIXABLE (x
))
3390 return SCM_MAKINUM (x
);
3392 return scm_long2big (x
);
3395 return scm_makdbl ((double) x
, 0.0);
3397 scm_num_overflow (s_sum
);
3398 return SCM_UNSPECIFIED
;
3406 SCM_GPROC1 (s_difference
, "-", scm_tc7_asubr
, scm_difference
, g_difference
);
3409 scm_difference (x
, y
)
3416 if (!(SCM_NIMP (x
)))
3420 SCM_GASSERT0 (!SCM_UNBNDP (x
), g_difference
,
3421 scm_makfrom0str (s_difference
), SCM_WNA
, 0);
3423 SCM_WTA_DISPATCH_1 (g_difference
, x
, SCM_ARG1
, s_difference
);
3428 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARG1
, s_difference
);
3436 x
= scm_copybig (x
, !SCM_BIGSIGN (x
));
3437 return (SCM_NUMDIGS (x
) * SCM_BITSPERDIG
/ SCM_CHAR_BIT
3439 ? scm_big2inum (x
, SCM_NUMDIGS (x
))
3443 SCM_ASRTGO (SCM_INEXP (x
), badx
);
3444 return scm_makdbl (- SCM_REALPART (x
),
3445 SCM_CPLXP (x
) ? -SCM_IMAG (x
) : 0.0);
3448 return scm_sum (x
, SCM_MAKINUM (- SCM_INUM (y
)));
3450 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3454 return ((SCM_NUMDIGS (x
) < SCM_NUMDIGS (y
))
3455 ? scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3458 : scm_addbig (SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3459 SCM_BIGSIGN (y
) ^ 0x0100,
3461 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3462 return scm_makdbl (scm_big2dbl (x
) - SCM_REALPART (y
),
3463 SCM_CPLXP (y
) ? -SCM_IMAG (y
) : 0.0);
3465 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3467 return scm_makdbl (SCM_REALPART (x
) - scm_big2dbl (y
),
3468 SCM_CPLXP (x
) ? SCM_IMAG (x
) : 0.0);
3469 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3471 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3472 SCM_ASRTGO (SCM_NIMP (y
) && SCM_INEXP (y
), bady
);
3477 return scm_makdbl (SCM_REAL (x
) - SCM_REAL (y
),
3478 SCM_IMAG (x
) - SCM_IMAG (y
));
3480 return scm_makdbl (SCM_REAL (x
) - SCM_REALPART (y
), SCM_IMAG (x
));
3482 return scm_makdbl (SCM_REALPART (x
) - SCM_REALPART (y
),
3483 SCM_CPLXP (y
) ? - SCM_IMAG (y
) : 0.0);
3493 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3496 #ifndef SCM_DIGSTOOBIG
3497 long z
= scm_pseudolong (SCM_INUM (x
));
3498 return scm_addbig ((SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3499 (x
< 0) ? 0x0100 : 0,
3502 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3503 scm_longdigs (SCM_INUM (x
), zdigs
);
3504 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3508 if (!(SCM_INEXP (y
)))
3511 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3514 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
3517 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3520 return scm_makdbl (SCM_INUM (x
) - SCM_REALPART (y
),
3521 SCM_CPLXP (y
) ? -SCM_IMAG (y
) : 0.0);
3527 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
3528 g_difference
, x
, y
, SCM_ARG1
, s_difference
);
3531 x
= scm_copybig (x
, !SCM_BIGSIGN (x
));
3532 return (SCM_NUMDIGS (x
) * SCM_BITSPERDIG
/ SCM_CHAR_BIT
3534 ? scm_big2inum (x
, SCM_NUMDIGS (x
))
3539 #ifndef SCM_DIGSTOOBIG
3540 long z
= scm_pseudolong (SCM_INUM (y
));
3541 return scm_addbig (&z
, SCM_DIGSPERLONG
, (y
< 0) ? 0 : 0x0100, x
, 0);
3543 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3544 scm_longdigs (SCM_INUM (x
), zdigs
);
3545 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (y
< 0) ? 0 : 0x0100,
3549 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3550 return (SCM_NUMDIGS (x
) < SCM_NUMDIGS (y
)) ?
3551 scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
), SCM_BIGSIGN (x
),
3553 scm_addbig (SCM_BDIGITS (y
), SCM_NUMDIGS (y
), SCM_BIGSIGN (y
) ^ 0x0100,
3563 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3566 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3569 #ifndef SCM_DIGSTOOBIG
3570 long z
= scm_pseudolong (SCM_INUM (x
));
3571 return scm_addbig (&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3574 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3575 scm_longdigs (SCM_INUM (x
), zdigs
);
3576 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3582 SCM_GASSERT2 (SCM_INUMP (x
), g_difference
, x
, y
, SCM_ARG1
, s_difference
);
3588 SCM_GASSERT2 (SCM_INUMP (y
), g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3591 x
= SCM_INUM (x
) - SCM_INUM (y
);
3593 if (SCM_FIXABLE (x
))
3594 return SCM_MAKINUM (x
);
3596 return scm_long2big (x
);
3599 return scm_makdbl ((double) x
, 0.0);
3601 scm_num_overflow (s_difference
);
3602 return SCM_UNSPECIFIED
;
3610 SCM_GPROC1 (s_product
, "*", scm_tc7_asubr
, scm_product
, g_product
);
3620 return SCM_MAKINUM (1L);
3621 SCM_GASSERT1 (SCM_NUMBERP (x
), g_product
, x
, SCM_ARG1
, s_product
);
3632 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARG1
, s_product
);
3643 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3645 return scm_mulbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3646 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3647 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
));
3648 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3651 double bg
= scm_big2dbl (x
);
3652 return scm_makdbl (bg
* SCM_REALPART (y
),
3653 SCM_CPLXP (y
) ? bg
* SCM_IMAG (y
) : 0.0);
3656 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3658 SCM_ASRTGO (SCM_NIMP (x
) && SCM_INEXP (x
), badx2
);
3668 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3676 else if (!(SCM_INEXP (y
)))
3679 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARGn
, s_product
);
3682 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
3685 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARGn
, s_product
);
3691 return scm_makdbl (SCM_REAL (x
) * SCM_REAL (y
)
3692 - SCM_IMAG (x
) * SCM_IMAG (y
),
3693 SCM_REAL (x
) * SCM_IMAG (y
)
3694 + SCM_IMAG (x
) * SCM_REAL (y
));
3696 return scm_makdbl (SCM_REAL (x
) * SCM_REALPART (y
),
3697 SCM_IMAG (x
) * SCM_REALPART (y
));
3699 return scm_makdbl (SCM_REALPART (x
) * SCM_REALPART (y
),
3701 ? SCM_REALPART (x
) * SCM_IMAG (y
)
3707 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3713 if (SCM_MAKINUM (1L) == x
)
3716 #ifndef SCM_DIGSTOOBIG
3717 long z
= scm_pseudolong (SCM_INUM (x
));
3718 return scm_mulbig ((SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3719 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3720 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3722 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3723 scm_longdigs (SCM_INUM (x
), zdigs
);
3724 return scm_mulbig (zdigs
, SCM_DIGSPERLONG
,
3725 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3726 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3730 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3732 SCM_ASRTGO (SCM_NIMP (y
) && SCM_INEXP (y
), bady
);
3735 return scm_makdbl (SCM_INUM (x
) * SCM_REALPART (y
),
3736 SCM_CPLXP (y
) ? SCM_INUM (x
) * SCM_IMAG (y
) : 0.0);
3742 SCM_ASRTGO (SCM_NIMP (x
) && SCM_BIGP (x
), badx2
);
3750 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3751 return scm_mulbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3752 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3753 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
));
3757 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3760 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARGn
, s_product
);
3765 if (SCM_MAKINUM (1L) == x
)
3768 #ifndef SCM_DIGSTOOBIG
3769 long z
= scm_pseudolong (SCM_INUM (x
));
3770 return scm_mulbig (&z
, SCM_DIGSPERLONG
,
3771 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3772 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3774 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3775 scm_longdigs (SCM_INUM (x
), zdigs
);
3776 return scm_mulbig (zdigs
, SCM_DIGSPERLONG
,
3777 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3778 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3783 SCM_ASRTGO (SCM_INUMP (x
), badx2
);
3784 SCM_GASSERT (SCM_INUMP (y
), g_product
, x
, y
, SCM_ARGn
, s_product
);
3794 y
= SCM_MAKINUM (k
);
3795 if (k
!= SCM_INUM (y
) || k
/ i
!= j
)
3798 int sgn
= (i
< 0) ^ (j
< 0);
3799 #ifndef SCM_DIGSTOOBIG
3800 i
= scm_pseudolong (i
);
3801 j
= scm_pseudolong (j
);
3802 return scm_mulbig ((SCM_BIGDIG
*) & i
, SCM_DIGSPERLONG
,
3803 (SCM_BIGDIG
*) & j
, SCM_DIGSPERLONG
, sgn
);
3804 #else /* SCM_DIGSTOOBIG */
3805 SCM_BIGDIG idigs
[SCM_DIGSPERLONG
];
3806 SCM_BIGDIG jdigs
[SCM_DIGSPERLONG
];
3807 scm_longdigs (i
, idigs
);
3808 scm_longdigs (j
, jdigs
);
3809 return scm_mulbig (idigs
, SCM_DIGSPERLONG
,
3810 jdigs
, SCM_DIGSPERLONG
,
3816 return scm_makdbl (((double) i
) * ((double) j
), 0.0);
3818 scm_num_overflow (s_product
);
3828 scm_num2dbl (a
, why
)
3833 return (double) SCM_INUM (a
);
3835 SCM_ASSERT (SCM_NIMP (a
), a
, "wrong type argument", why
);
3837 return (SCM_REALPART (a
));
3840 return scm_big2dbl (a
);
3842 SCM_ASSERT (0, a
, "wrong type argument", why
);
3843 return SCM_UNSPECIFIED
;
3847 SCM_GPROC1 (s_divide
, "/", scm_tc7_asubr
, scm_divide
, g_divide
);
3858 if (!(SCM_NIMP (x
)))
3862 SCM_GASSERT0 (!SCM_UNBNDP (x
),
3863 g_divide
, scm_makfrom0str (s_divide
), SCM_WNA
, 0);
3865 SCM_WTA_DISPATCH_1 (g_divide
, x
, SCM_ARG1
, s_divide
);
3870 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARG1
, s_divide
);
3877 return scm_makdbl (1.0 / scm_big2dbl (x
), 0.0);
3879 SCM_ASRTGO (SCM_INEXP (x
), badx
);
3881 return scm_makdbl (1.0 / SCM_REALPART (x
), 0.0);
3885 return scm_makdbl (r
/ d
, -i
/ d
);
3894 #ifndef SCM_RECKLESS
3896 scm_num_overflow (s_divide
);
3904 SCM w
= scm_copybig (x
, SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0));
3905 return (scm_divbigdig (SCM_BDIGITS (w
), SCM_NUMDIGS (w
),
3907 ? scm_makdbl (scm_big2dbl (x
) / SCM_INUM (y
), 0.0)
3910 #ifndef SCM_DIGSTOOBIG
3911 z
= scm_pseudolong (z
);
3912 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3913 (SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3914 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
3917 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3918 scm_longdigs (z
, zdigs
);
3919 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3920 zdigs
, SCM_DIGSPERLONG
,
3921 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
3924 return z
? z
: scm_makdbl (scm_big2dbl (x
) / SCM_INUM (y
), 0.0);
3926 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3929 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3930 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3931 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
), 3);
3932 return z
? z
: scm_makdbl (scm_big2dbl (x
) / scm_big2dbl (y
),
3935 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3937 return scm_makdbl (scm_big2dbl (x
) / SCM_REALPART (y
), 0.0);
3938 a
= scm_big2dbl (x
);
3942 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3949 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3952 d
= scm_big2dbl (y
);
3955 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3957 SCM_ASRTGO (SCM_NIMP (y
) && SCM_INEXP (y
), bady
);
3961 d
= SCM_REALPART (y
);
3963 return scm_makdbl (SCM_REALPART (x
) / d
,
3964 SCM_CPLXP (x
) ? SCM_IMAG (x
) / d
: 0.0);
3966 a
= SCM_REALPART (x
);
3972 return scm_makdbl ((a
* r
+ SCM_IMAG (x
) * i
) / d
,
3973 (SCM_IMAG (x
) * r
- a
* i
) / d
);
3977 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
3979 return scm_makdbl (1.0 / ((double) SCM_INUM (x
)), 0.0);
3984 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3986 return scm_makdbl (SCM_INUM (x
) / scm_big2dbl (y
), 0.0);
3987 if (!(SCM_INEXP (y
)))
3990 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARGn
, s_divide
);
3993 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
3996 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARGn
, s_divide
);
4000 return scm_makdbl (SCM_INUM (x
) / SCM_REALPART (y
), 0.0);
4006 return scm_makdbl ((a
* r
) / d
, (-a
* i
) / d
);
4013 SCM_GASSERT2 (SCM_NIMP (x
) && SCM_BIGP (x
),
4014 g_divide
, x
, y
, SCM_ARG1
, s_divide
);
4028 SCM w
= scm_copybig (x
, SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0));
4029 if (scm_divbigdig (SCM_BDIGITS (w
), SCM_NUMDIGS (w
),
4034 #ifndef SCM_DIGSTOOBIG
4035 z
= scm_pseudolong (z
);
4036 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
4037 &z
, SCM_DIGSPERLONG
,
4038 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
4041 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
4042 scm_longdigs (z
, zdigs
);
4043 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
4044 zdigs
, SCM_DIGSPERLONG
,
4045 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
4051 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
4052 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
4053 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
4054 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
), 3);
4062 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
4068 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
4071 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARGn
, s_divide
);
4076 SCM_GASSERT2 (SCM_INUMP (x
), g_divide
, x
, y
, SCM_ARG1
, s_divide
);
4079 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
4083 SCM_GASSERT2 (SCM_INUMP (y
), g_divide
, x
, y
, SCM_ARGn
, s_divide
);
4087 long z
= SCM_INUM (y
);
4088 if ((0 == z
) || SCM_INUM (x
) % z
)
4090 z
= SCM_INUM (x
) / z
;
4091 if (SCM_FIXABLE (z
))
4092 return SCM_MAKINUM (z
);
4094 return scm_long2big (z
);
4098 return scm_makdbl (((double) SCM_INUM (x
)) / ((double) SCM_INUM (y
)), 0.0);
4101 scm_num_overflow (s_divide
);
4102 return SCM_UNSPECIFIED
;
4111 SCM_GPROC1 (s_asinh
, "$asinh", scm_tc7_cxr
, (SCM (*)()) scm_asinh
, g_asinh
);
4117 return log (x
+ sqrt (x
* x
+ 1));
4123 SCM_GPROC1 (s_acosh
, "$acosh", scm_tc7_cxr
, (SCM (*)()) scm_acosh
, g_acosh
);
4129 return log (x
+ sqrt (x
* x
- 1));
4135 SCM_GPROC1 (s_atanh
, "$atanh", scm_tc7_cxr
, (SCM (*)()) scm_atanh
, g_atanh
);
4141 return 0.5 * log ((1 + x
) / (1 - x
));
4147 SCM_GPROC1 (s_truncate
, "truncate", scm_tc7_cxr
, (SCM (*)()) scm_truncate
, g_truncate
);
4160 SCM_GPROC1 (s_round
, "round", scm_tc7_cxr
, (SCM (*)()) scm_round
, g_round
);
4166 double plus_half
= x
+ 0.5;
4167 double result
= floor (plus_half
);
4168 /* Adjust so that the scm_round is towards even. */
4169 return (plus_half
== result
&& plus_half
/ 2 != floor (plus_half
/ 2))
4170 ? result
- 1 : result
;
4175 SCM_GPROC1 (s_exact_to_inexact
, "exact->inexact", scm_tc7_cxr
, (SCM (*)()) scm_exact_to_inexact
, g_exact_to_inexact
);
4178 scm_exact_to_inexact (z
)
4185 SCM_GPROC1 (s_i_floor
, "floor", scm_tc7_cxr
, (SCM (*)()) floor
, g_i_floor
);
4186 SCM_GPROC1 (s_i_ceil
, "ceiling", scm_tc7_cxr
, (SCM (*)()) ceil
, g_i_ceil
);
4187 SCM_GPROC1 (s_i_sqrt
, "$sqrt", scm_tc7_cxr
, (SCM (*)()) sqrt
, g_i_sqrt
);
4188 SCM_GPROC1 (s_i_abs
, "$abs", scm_tc7_cxr
, (SCM (*)()) fabs
, g_i_abs
);
4189 SCM_GPROC1 (s_i_exp
, "$exp", scm_tc7_cxr
, (SCM (*)()) exp
, g_i_exp
);
4190 SCM_GPROC1 (s_i_log
, "$log", scm_tc7_cxr
, (SCM (*)()) log
, g_i_log
);
4191 SCM_GPROC1 (s_i_sin
, "$sin", scm_tc7_cxr
, (SCM (*)()) sin
, g_i_sin
);
4192 SCM_GPROC1 (s_i_cos
, "$cos", scm_tc7_cxr
, (SCM (*)()) cos
, g_i_cos
);
4193 SCM_GPROC1 (s_i_tan
, "$tan", scm_tc7_cxr
, (SCM (*)()) tan
, g_i_tan
);
4194 SCM_GPROC1 (s_i_asin
, "$asin", scm_tc7_cxr
, (SCM (*)()) asin
, g_i_asin
);
4195 SCM_GPROC1 (s_i_acos
, "$acos", scm_tc7_cxr
, (SCM (*)()) acos
, g_i_acos
);
4196 SCM_GPROC1 (s_i_atan
, "$atan", scm_tc7_cxr
, (SCM (*)()) atan
, g_i_atan
);
4197 SCM_GPROC1 (s_i_sinh
, "$sinh", scm_tc7_cxr
, (SCM (*)()) sinh
, g_i_sinh
);
4198 SCM_GPROC1 (s_i_cosh
, "$cosh", scm_tc7_cxr
, (SCM (*)()) cosh
, g_i_cosh
);
4199 SCM_GPROC1 (s_i_tanh
, "$tanh", scm_tc7_cxr
, (SCM (*)()) tanh
, g_i_tanh
);
4206 static void scm_two_doubles (SCM z1
,
4208 const char *sstring
,
4212 scm_two_doubles (z1
, z2
, sstring
, xy
)
4214 const char *sstring
;
4218 xy
->x
= SCM_INUM (z1
);
4222 SCM_ASRTGO (SCM_NIMP (z1
), badz1
);
4224 xy
->x
= scm_big2dbl (z1
);
4227 #ifndef SCM_RECKLESS
4228 if (!(SCM_REALP (z1
)))
4229 badz1
:scm_wta (z1
, (char *) SCM_ARG1
, sstring
);
4231 xy
->x
= SCM_REALPART (z1
);
4235 SCM_ASSERT (SCM_NIMP (z1
) && SCM_REALP (z1
), z1
, SCM_ARG1
, sstring
);
4236 xy
->x
= SCM_REALPART (z1
);
4241 xy
->y
= SCM_INUM (z2
);
4245 SCM_ASRTGO (SCM_NIMP (z2
), badz2
);
4247 xy
->y
= scm_big2dbl (z2
);
4250 #ifndef SCM_RECKLESS
4251 if (!(SCM_REALP (z2
)))
4252 badz2
:scm_wta (z2
, (char *) SCM_ARG2
, sstring
);
4254 xy
->y
= SCM_REALPART (z2
);
4258 SCM_ASSERT (SCM_NIMP (z2
) && SCM_REALP (z2
), z2
, SCM_ARG2
, sstring
);
4259 xy
->y
= SCM_REALPART (z2
);
4268 SCM_PROC (s_sys_expt
, "$expt", 2, 0, 0, scm_sys_expt
);
4271 scm_sys_expt (z1
, z2
)
4276 scm_two_doubles (z1
, z2
, s_sys_expt
, &xy
);
4277 return scm_makdbl (pow (xy
.x
, xy
.y
), 0.0);
4282 SCM_PROC (s_sys_atan2
, "$atan2", 2, 0, 0, scm_sys_atan2
);
4285 scm_sys_atan2 (z1
, z2
)
4290 scm_two_doubles (z1
, z2
, s_sys_atan2
, &xy
);
4291 return scm_makdbl (atan2 (xy
.x
, xy
.y
), 0.0);
4296 SCM_PROC (s_make_rectangular
, "make-rectangular", 2, 0, 0, scm_make_rectangular
);
4299 scm_make_rectangular (z1
, z2
)
4304 scm_two_doubles (z1
, z2
, s_make_rectangular
, &xy
);
4305 return scm_makdbl (xy
.x
, xy
.y
);
4310 SCM_PROC (s_make_polar
, "make-polar", 2, 0, 0, scm_make_polar
);
4313 scm_make_polar (z1
, z2
)
4318 scm_two_doubles (z1
, z2
, s_make_polar
, &xy
);
4319 return scm_makdbl (xy
.x
* cos (xy
.y
), xy
.x
* sin (xy
.y
));
4325 SCM_GPROC (s_real_part
, "real-part", 1, 0, 0, scm_real_part
, g_real_part
);
4334 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4337 if (!(SCM_INEXP (z
)))
4340 SCM_WTA_DISPATCH_1 (g_real_part
, z
, SCM_ARG1
, s_real_part
);
4343 SCM_GASSERT1 (SCM_NIMP (z
) && SCM_INEXP (z
),
4344 g_real_part
, z
, SCM_ARG1
, s_real_part
);
4347 return scm_makdbl (SCM_REAL (z
), 0.0);
4354 SCM_GPROC (s_imag_part
, "imag-part", 1, 0, 0, scm_imag_part
, g_imag_part
);
4363 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4366 if (!(SCM_INEXP (z
)))
4369 SCM_WTA_DISPATCH_1 (g_imag_part
, z
, SCM_ARG1
, s_imag_part
);
4372 SCM_GASSERT1 (SCM_NIMP (z
) && SCM_INEXP (z
),
4373 g_imag_part
, z
, SCM_ARG1
, s_imag_part
);
4376 return scm_makdbl (SCM_IMAG (z
), 0.0);
4382 SCM_GPROC (s_magnitude
, "magnitude", 1, 0, 0, scm_magnitude
, g_magnitude
);
4391 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4394 if (!(SCM_INEXP (z
)))
4397 SCM_WTA_DISPATCH_1 (g_magnitude
, z
, SCM_ARG1
, s_magnitude
);
4400 SCM_GASSERT1 (SCM_NIMP (z
) && SCM_INEXP (z
),
4401 g_magnitude
, z
, SCM_ARG1
, s_magnitude
);
4405 double i
= SCM_IMAG (z
), r
= SCM_REAL (z
);
4406 return scm_makdbl (sqrt (i
* i
+ r
* r
), 0.0);
4408 return scm_makdbl (fabs (SCM_REALPART (z
)), 0.0);
4414 SCM_GPROC (s_angle
, "angle", 1, 0, 0, scm_angle
, g_angle
);
4423 x
= (z
>= SCM_INUM0
) ? 1.0 : -1.0;
4427 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4430 x
= (SCM_TYP16 (z
) == scm_tc16_bigpos
) ? 1.0 : -1.0;
4433 if (!(SCM_INEXP (z
)))
4436 SCM_WTA_DISPATCH_1 (g_angle
, z
, SCM_ARG1
, s_angle
);
4439 SCM_GASSERT1 (SCM_NIMP (z
) && SCM_INEXP (z
), g_angle
, z
, SCM_ARG1
, s_angle
);
4443 x
= SCM_REALPART (z
);
4449 return scm_makdbl (atan2 (y
, x
), 0.0);
4453 SCM_PROC (s_inexact_to_exact
, "inexact->exact", 1, 0, 0, scm_inexact_to_exact
);
4456 scm_inexact_to_exact (z
)
4462 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4465 #ifndef SCM_RECKLESS
4466 if (!(SCM_REALP (z
)))
4469 scm_wta (z
, (char *) SCM_ARG1
, s_inexact_to_exact
);
4473 SCM_ASSERT (SCM_NIMP (z
) && SCM_REALP (z
), z
, SCM_ARG1
, s_inexact_to_exact
);
4477 double u
= floor (SCM_REALPART (z
) + 0.5);
4478 if ((u
<= SCM_MOST_POSITIVE_FIXNUM
) && (-u
<= -SCM_MOST_NEGATIVE_FIXNUM
))
4480 /* Negation is a workaround for HP700 cc bug */
4481 SCM ans
= SCM_MAKINUM ((long) u
);
4482 if (SCM_INUM (ans
) == (long) u
)
4485 SCM_ASRTGO (isfinite (u
), badz
); /* problem? */
4486 return scm_dbl2big (u
);
4489 return SCM_MAKINUM ((long) floor (SCM_REALPART (z
) + 0.5));
4495 #else /* ~SCM_FLOATS */
4496 SCM_GPROC (s_trunc
, "truncate", 1, 0, 0, scm_trunc
, g_trunc
);
4502 SCM_GASSERT2 (SCM_INUMP (x
), g_trunc
, x
, y
, SCM_ARG1
, s_truncate
);
4508 #endif /* SCM_FLOATS */
4512 /* d must be integer */
4522 double u
= (d
< 0) ? -d
: d
;
4523 while (0 != floor (u
))
4528 ans
= scm_mkbig (i
, d
< 0);
4529 digits
= SCM_BDIGITS (ans
);
4537 #ifndef SCM_RECKLESS
4539 scm_num_overflow ("dbl2big");
4551 scm_sizet i
= SCM_NUMDIGS (b
);
4552 SCM_BIGDIG
*digits
= SCM_BDIGITS (b
);
4554 ans
= digits
[i
] + SCM_BIGRAD
* ans
;
4555 if (scm_tc16_bigneg
== SCM_TYP16 (b
))
4567 if (!SCM_FIXABLE (sl
))
4570 return scm_long2big (sl
);
4573 return scm_makdbl ((double) sl
, 0.0);
4579 return SCM_MAKINUM (sl
);
4586 scm_long_long2num (sl
)
4589 if (!SCM_FIXABLE (sl
))
4592 return scm_long_long2big (sl
);
4595 return scm_makdbl ((double) sl
, 0.0);
4601 return SCM_MAKINUM (sl
);
4611 if (!SCM_POSFIXABLE (sl
))
4614 return scm_ulong2big (sl
);
4617 return scm_makdbl ((double) sl
, 0.0);
4623 return SCM_MAKINUM (sl
);
4628 scm_num2long (num
, pos
, s_caller
)
4631 const char *s_caller
;
4634 if (SCM_INUMP (num
))
4636 res
= SCM_INUM (num
);
4639 SCM_ASRTGO (SCM_NIMP (num
), errout
);
4641 if (SCM_REALP (num
))
4643 double u
= SCM_REALPART (num
);
4645 if ((double) res
== u
)
4658 for (l
= SCM_NUMDIGS (num
); l
--;)
4660 res
= SCM_BIGUP (res
) + SCM_BDIGITS (num
)[l
];
4665 if (SCM_TYP16 (num
) == scm_tc16_bigpos
)
4672 scm_wta (num
, pos
, s_caller
);
4673 return SCM_UNSPECIFIED
;
4681 scm_num2long_long (num
, pos
, s_caller
)
4684 const char *s_caller
;
4687 if (SCM_INUMP (num
))
4689 res
= SCM_INUM ((long_long
) num
);
4692 SCM_ASRTGO (SCM_NIMP (num
), errout
);
4694 if (SCM_REALP (num
))
4696 double u
= SCM_REALPART (num
);
4697 if (((SCM_MOST_NEGATIVE_FIXNUM
* 4) <= u
)
4698 && (u
<= (SCM_MOST_POSITIVE_FIXNUM
* 4 + 3)))
4708 scm_sizet l
= SCM_NUMDIGS (num
);
4709 SCM_ASRTGO (SCM_DIGSPERLONGLONG
>= l
, errout
);
4712 res
= SCM_LONGLONGBIGUP (res
) + SCM_BDIGITS (num
)[l
];
4717 scm_wta (num
, pos
, s_caller
);
4718 return SCM_UNSPECIFIED
;
4725 scm_num2ulong (num
, pos
, s_caller
)
4728 const char *s_caller
;
4731 if (SCM_INUMP (num
))
4733 res
= SCM_INUM ((unsigned long) num
);
4736 SCM_ASRTGO (SCM_NIMP (num
), errout
);
4738 if (SCM_REALP (num
))
4740 double u
= SCM_REALPART (num
);
4741 if ((0 <= u
) && (u
<= (unsigned long) ~0L))
4751 unsigned long oldres
;
4755 for (l
= SCM_NUMDIGS (num
); l
--;)
4757 res
= SCM_BIGUP (res
) + SCM_BDIGITS (num
)[l
];
4766 scm_wta (num
, pos
, s_caller
);
4767 return SCM_UNSPECIFIED
;
4773 static void add1
SCM_P ((double f
, double *fsum
));
4788 scm_add_feature("complex");
4790 scm_add_feature("inexact");
4792 SCM_NEWSMOB(scm_flo0
,scm_tc_flo
,NULL
);
4794 SCM_NEWSMOB(scm_flo0
,scm_tc_dblr
,scm_must_malloc (1L * sizeof (double), "real"));
4795 SCM_REAL (scm_flo0
) = 0.0;
4798 scm_dblprec
= (DBL_DIG
> 20) ? 20 : DBL_DIG
;
4800 { /* determine floating point precision */
4802 double fsum
= 1.0 + f
;
4806 if (++scm_dblprec
> 20)
4810 scm_dblprec
= scm_dblprec
- 1;
4812 #endif /* DBL_DIG */
4814 #include "numbers.x"