1 /* Copyright (C) 1995,1996, 1997 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. */
51 #define DIGITS '0':case '1':case '2':case '3':case '4':\
52 case '5':case '6':case '7':case '8':case '9'
55 /* IS_INF tests its floating point number for infiniteness
58 # define IS_INF(x) ((x)==(x)/2)
61 /* MAXEXP is the maximum double precision expontent
62 * FLTMAX is less than or scm_equal the largest single precision float
69 # endif /* ndef GO32 */
70 # endif /* def STDC_HEADERS */
71 # ifdef DBL_MAX_10_EXP
72 # define MAXEXP DBL_MAX_10_EXP
74 # define MAXEXP 308 /* IEEE doubles */
75 # endif /* def DBL_MAX_10_EXP */
77 # define FLTMAX FLT_MAX
80 # endif /* def FLT_MAX */
81 #endif /* def SCM_FLOATS */
85 SCM_PROC(s_exact_p
, "exact?", 1, 0, 0, scm_exact_p
);
91 if SCM_INUMP(x
) return SCM_BOOL_T
;
93 if (SCM_NIMP(x
) && SCM_BIGP(x
)) return SCM_BOOL_T
;
98 SCM_PROC(s_odd_p
, "odd?", 1, 0, 0, scm_odd_p
);
106 SCM_ASSERT(SCM_NIMP(n
) && SCM_BIGP(n
), n
, SCM_ARG1
, s_odd_p
);
107 return (1 & SCM_BDIGITS(n
)[0]) ? SCM_BOOL_T
: SCM_BOOL_F
;
110 SCM_ASSERT(SCM_INUMP(n
), n
, SCM_ARG1
, s_odd_p
);
112 return (4 & (int)n
) ? SCM_BOOL_T
: SCM_BOOL_F
;
115 SCM_PROC(s_even_p
, "even?", 1, 0, 0, scm_even_p
);
123 SCM_ASSERT(SCM_NIMP(n
) && SCM_BIGP(n
), n
, SCM_ARG1
, s_even_p
);
124 return (1 & SCM_BDIGITS(n
)[0]) ? SCM_BOOL_F
: SCM_BOOL_T
;
127 SCM_ASSERT(SCM_INUMP(n
), n
, SCM_ARG1
, s_even_p
);
129 return (4 & (int)n
) ? SCM_BOOL_F
: SCM_BOOL_T
;
132 SCM_PROC(s_abs
, "abs", 1, 0, 0, scm_abs
);
140 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_abs
);
141 if (SCM_TYP16(x
)==scm_tc16_bigpos
) return x
;
142 return scm_copybig(x
, 0);
145 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_abs
);
147 if (SCM_INUM(x
) >= 0) return x
;
149 if (!SCM_POSFIXABLE(x
))
151 return scm_long2big(x
);
153 scm_num_overflow (s_abs
);
155 return SCM_MAKINUM(x
);
158 SCM_PROC(s_quotient
, "quotient", 2, 0, 0, scm_quotient
);
169 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_quotient
);
171 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
172 return scm_divbigbig(SCM_BDIGITS(x
),
176 SCM_BIGSIGN(x
) ^ SCM_BIGSIGN(y
),
183 if (z
< SCM_BIGRAD
) {
184 w
= scm_copybig(x
, SCM_BIGSIGN(x
) ? (y
>0) : (y
<0));
185 scm_divbigdig(SCM_BDIGITS(w
), SCM_NUMDIGS(w
), (SCM_BIGDIG
)z
);
186 return scm_normbig(w
);
188 #ifndef SCM_DIGSTOOBIG
189 w
= scm_pseudolong(z
);
190 return scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), (SCM_BIGDIG
*)&w
, SCM_DIGSPERLONG
,
191 SCM_BIGSIGN(x
) ? (y
>0) : (y
<0), 2);
193 { SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
194 scm_longdigs(z
, zdigs
);
195 return scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), zdigs
, SCM_DIGSPERLONG
,
196 SCM_BIGSIGN(x
) ? (y
>0) : (y
<0), 2);
202 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
203 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_quotient
);
208 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_quotient
);
209 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_quotient
);
211 if ((z
= SCM_INUM(y
))==0)
212 ov
: scm_num_overflow (s_quotient
);
217 long t
= ((y
<0) ? -SCM_INUM(x
) : SCM_INUM(x
))%SCM_INUM(y
);
219 long t
= SCM_INUM(x
)%SCM_INUM(y
);
230 return scm_long2big(z
);
232 scm_num_overflow (s_quotient
);
234 return SCM_MAKINUM(z
);
237 SCM_PROC(s_remainder
, "remainder", 2, 0, 0, scm_remainder
);
247 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_remainder
);
249 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
250 return scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
253 if (!(z
= SCM_INUM(y
))) goto ov
;
254 return scm_divbigint(x
, z
, SCM_BIGSIGN(x
), 0);
258 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
259 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_remainder
);
264 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_remainder
);
265 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_remainder
);
267 if (!(z
= SCM_INUM(y
)))
268 ov
: scm_num_overflow (s_remainder
);
277 else z
+= SCM_INUM(y
);
278 else if (x
< 0) z
-= SCM_INUM(y
);
280 return SCM_MAKINUM(z
);
283 SCM_PROC(s_modulo
, "modulo", 2, 0, 0, scm_modulo
);
293 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_modulo
);
295 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
296 return scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
297 SCM_BIGSIGN(y
), (SCM_BIGSIGN(x
) ^ SCM_BIGSIGN(y
)) ? 1 : 0);
299 if (!(z
= SCM_INUM(y
))) goto ov
;
300 return scm_divbigint(x
, z
, y
< 0, (SCM_BIGSIGN(x
) ? (y
> 0) : (y
< 0)) ? 1 : 0);
304 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
305 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_modulo
);
307 return (SCM_BIGSIGN(y
) ? (x
>0) : (x
<0)) ? scm_sum(x
, y
) : x
;
310 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_modulo
);
311 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_modulo
);
313 if (!(yy
= SCM_INUM(y
)))
314 ov
: scm_num_overflow (s_modulo
);
317 z
= ((yy
<0) ? -z
: z
)%yy
;
321 return SCM_MAKINUM(((yy
<0) ? (z
>0) : (z
<0)) ? z
+yy
: z
);
324 SCM_PROC1 (s_gcd
, "gcd", scm_tc7_asubr
, scm_gcd
);
331 register long u
, v
, k
, t
;
332 if SCM_UNBNDP(y
) return SCM_UNBNDP(x
) ? SCM_INUM0
: x
;
337 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_gcd
);
338 if SCM_BIGSIGN(x
) x
= scm_copybig(x
, 0);
341 SCM_ASSERT(SCM_NIMP(y
) && SCM_BIGP(y
), y
, SCM_ARG2
, s_gcd
);
342 if SCM_BIGSIGN(y
) y
= scm_copybig(y
, 0);
343 switch (scm_bigcomp(x
, y
)) {
345 swaprec
: t
= scm_remainder(x
, y
); x
= y
; y
= t
; goto tailrec
;
347 case 1: y
= scm_remainder(y
, x
); goto newy
;
349 /* instead of the switch, we could just return scm_gcd(y, scm_modulo(x, y)); */
351 if (SCM_INUM0
==y
) return x
; goto swaprec
;
353 if SCM_NINUMP(y
) { t
=x
; x
=y
; y
=t
; goto big_gcd
;}
355 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_gcd
);
356 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_gcd
);
362 else if (0==v
) goto getout
;
363 if (0==u
) {u
= v
; goto getout
;}
364 for (k
= 1;!(1 & ((int)u
|(int)v
));k
<<= 1, u
>>= 1, v
>>= 1);
365 if (1 & (int)u
) t
= -v
;
371 if (!(1 & (int)t
)) goto b3
;
374 if ((t
= u
-v
)) goto b3
;
377 if (!SCM_POSFIXABLE(u
))
379 return scm_long2big(u
);
381 scm_num_overflow (s_gcd
);
383 return SCM_MAKINUM(u
);
386 SCM_PROC1 (s_lcm
, "lcm", scm_tc7_asubr
, scm_lcm
);
395 n2
= SCM_MAKINUM(1L);
396 if SCM_UNBNDP(n1
) return n2
;
399 if (SCM_INUM0
==d
) return d
;
400 return scm_abs(scm_product(n1
, scm_quotient(n2
, d
)));
405 # define scm_long2num SCM_MAKINUM
410 SCM_PROC1 (s_logand
, "logand", scm_tc7_asubr
, scm_logand
);
420 return SCM_MAKINUM (-1);
423 return scm_long2num (scm_num2long(n1
, (char *)SCM_ARG1
, s_logand
)
424 & scm_num2long(n2
, (char *)SCM_ARG2
, s_logand
));
427 SCM_PROC1 (s_logior
, "logior", scm_tc7_asubr
, scm_logior
);
440 return scm_long2num(scm_num2long(n1
, (char *)SCM_ARG1
, s_logior
)
441 | scm_num2long(n2
, (char *)SCM_ARG2
, s_logior
));
444 SCM_PROC1 (s_logxor
, "logxor", scm_tc7_asubr
, scm_logxor
);
457 return scm_long2num(scm_num2long(n1
, (char *)SCM_ARG1
, s_logxor
)
458 ^ scm_num2long(n2
, (char *)SCM_ARG2
, s_logxor
));
461 SCM_PROC(s_logtest
, "logtest", 2, 0, 0, scm_logtest
);
468 return ((scm_num2long (n1
, (char *)SCM_ARG1
, s_logtest
)
469 & scm_num2long (n2
, (char *)SCM_ARG2
, s_logtest
))
470 ? SCM_BOOL_T
: SCM_BOOL_F
);
474 SCM_PROC(s_logbit_p
, "logbit?", 2, 0, 0, scm_logbit_p
);
481 return (((1 << scm_num2long (n1
, (char *)SCM_ARG1
, s_logtest
))
482 & scm_num2long (n2
, (char *)SCM_ARG2
, s_logtest
))
483 ? SCM_BOOL_T
: SCM_BOOL_F
);
488 SCM_PROC1 (s_logand
, "logand", scm_tc7_asubr
, scm_logand
);
498 return SCM_MAKINUM (-1);
501 return SCM_MAKINUM(SCM_INUM(n1
) & SCM_INUM(n2
));
504 SCM_PROC1 (s_logior
, "logior", scm_tc7_asubr
, scm_logior
);
517 return SCM_MAKINUM(SCM_INUM(n1
) | SCM_INUM(n2
));
520 SCM_PROC1 (s_logxor
, "logxor", scm_tc7_asubr
, scm_logxor
);
533 return SCM_MAKINUM(SCM_INUM(n1
) ^ SCM_INUM(n2
));
536 SCM_PROC(s_logtest
, "logtest", 2, 0, 0, scm_logtest
);
543 SCM_ASSERT(SCM_INUMP(n1
), n1
, SCM_ARG1
, s_logtest
);
544 SCM_ASSERT(SCM_INUMP(n2
), n2
, SCM_ARG2
, s_logtest
);
545 return (SCM_INUM(n1
) & SCM_INUM(n2
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
548 SCM_PROC(s_logbit_p
, "logbit?", 2, 0, 0, scm_logbit_p
);
555 SCM_ASSERT(SCM_INUMP(n1
) && SCM_INUM(n1
) >= 0, n1
, SCM_ARG1
, s_logbit_p
);
556 SCM_ASSERT(SCM_INUMP(n2
), n2
, SCM_ARG2
, s_logbit_p
);
557 return ((1 << SCM_INUM(n1
)) & SCM_INUM(n2
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
561 SCM_PROC(s_lognot
, "lognot", 1, 0, 0, scm_lognot
);
567 SCM_ASSERT(SCM_INUMP(n
), n
, SCM_ARG1
, s_lognot
);
568 return scm_difference(SCM_MAKINUM(-1L), n
);
571 SCM_PROC(s_integer_expt
, "integer-expt", 2, 0, 0, scm_integer_expt
);
574 scm_integer_expt(z1
, z2
)
578 SCM acc
= SCM_MAKINUM(1L);
580 if (SCM_INUM0
==z1
|| acc
==z1
) return z1
;
581 else if (SCM_MAKINUM(-1L)==z1
) return SCM_BOOL_F
==scm_even_p(z2
)?z1
:acc
;
583 SCM_ASSERT(SCM_INUMP(z2
), z2
, SCM_ARG2
, s_integer_expt
);
587 z1
= scm_divide(z1
, SCM_UNDEFINED
);
590 if (0==z2
) return acc
;
591 if (1==z2
) return scm_product(acc
, z1
);
592 if (z2
& 1) acc
= scm_product(acc
, z1
);
593 z1
= scm_product(z1
, z1
);
598 SCM_PROC(s_ash
, "ash", 2, 0, 0, scm_ash
);
605 SCM res
= SCM_INUM(n
);
606 SCM_ASSERT(SCM_INUMP(cnt
), cnt
, SCM_ARG2
, s_ash
);
609 res
= scm_integer_expt(SCM_MAKINUM(2), SCM_MAKINUM(-SCM_INUM(cnt
)));
610 if (SCM_NFALSEP(scm_negative_p(n
)))
611 return scm_sum(SCM_MAKINUM(-1L), scm_quotient(scm_sum(SCM_MAKINUM(1L), n
), res
));
612 else return scm_quotient(n
, res
);
614 else return scm_product(n
, scm_integer_expt(SCM_MAKINUM(2), cnt
));
616 SCM_ASSERT(SCM_INUMP(n
), n
, SCM_ARG1
, s_ash
);
618 if (cnt
< 0) return SCM_MAKINUM(SCM_SRS(res
, -cnt
));
619 res
= SCM_MAKINUM(res
<<cnt
);
620 if (SCM_INUM(res
)>>cnt
!= SCM_INUM(n
))
621 scm_num_overflow (s_ash
);
626 SCM_PROC(s_bit_extract
, "bit-extract", 3, 0, 0, scm_bit_extract
);
629 scm_bit_extract(n
, start
, end
)
634 SCM_ASSERT(SCM_INUMP(start
), start
, SCM_ARG2
, s_bit_extract
);
635 SCM_ASSERT(SCM_INUMP(end
), end
, SCM_ARG3
, s_bit_extract
);
636 start
= SCM_INUM(start
); end
= SCM_INUM(end
);
637 SCM_ASSERT(end
>= start
, SCM_MAKINUM(end
), SCM_OUTOFRANGE
, s_bit_extract
);
641 scm_logand(scm_difference(scm_integer_expt(SCM_MAKINUM(2), SCM_MAKINUM(end
- start
)),
643 scm_ash(n
, SCM_MAKINUM(-start
)));
645 SCM_ASSERT(SCM_INUMP(n
), n
, SCM_ARG1
, s_bit_extract
);
647 return SCM_MAKINUM((SCM_INUM(n
)>>start
) & ((1L<<(end
-start
))-1));
650 char scm_logtab
[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
651 SCM_PROC(s_logcount
, "logcount", 1, 0, 0, scm_logcount
);
657 register unsigned long c
= 0;
661 scm_sizet i
; SCM_BIGDIG
*ds
, d
;
662 SCM_ASSERT(SCM_NIMP(n
) && SCM_BIGP(n
), n
, SCM_ARG1
, s_logcount
);
663 if SCM_BIGSIGN(n
) return scm_logcount(scm_difference(SCM_MAKINUM(-1L), n
));
665 for(i
= SCM_NUMDIGS(n
); i
--; )
666 for(d
= ds
[i
]; d
; d
>>= 4) c
+= scm_logtab
[15 & d
];
667 return SCM_MAKINUM(c
);
670 SCM_ASSERT(SCM_INUMP(n
), n
, SCM_ARG1
, s_logcount
);
672 if ((nn
= SCM_INUM(n
)) < 0) nn
= -1 - nn
;
673 for(; nn
; nn
>>= 4) c
+= scm_logtab
[15 & nn
];
674 return SCM_MAKINUM(c
);
677 char scm_ilentab
[] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4};
678 SCM_PROC(s_integer_length
, "integer-length", 1, 0, 0, scm_integer_length
);
681 scm_integer_length(n
)
684 register unsigned long c
= 0;
690 SCM_ASSERT(SCM_NIMP(n
) && SCM_BIGP(n
), n
, SCM_ARG1
, s_integer_length
);
691 if SCM_BIGSIGN(n
) return scm_integer_length(scm_difference(SCM_MAKINUM(-1L), n
));
693 d
= ds
[c
= SCM_NUMDIGS(n
)-1];
694 for(c
*= SCM_BITSPERDIG
; d
; d
>>= 4) {c
+= 4; l
= scm_ilentab
[15 & d
];}
695 return SCM_MAKINUM(c
- 4 + l
);
698 SCM_ASSERT(SCM_INUMP(n
), n
, SCM_ARG1
, s_integer_length
);
700 if ((nn
= SCM_INUM(n
)) < 0) nn
= -1 - nn
;
701 for(;nn
; nn
>>= 4) {c
+= 4; l
= scm_ilentab
[15 & nn
];}
702 return SCM_MAKINUM(c
- 4 + l
);
707 char s_bignum
[] = "bignum";
710 scm_mkbig(nlen
, sign
)
715 /* Cast to SCM to avoid signed/unsigned comparison warnings. */
716 if (((v
<< 16) >> 16) != (SCM
) nlen
)
717 scm_wta(SCM_MAKINUM(nlen
), (char *)SCM_NALLOC
, s_bignum
);
720 SCM_SETCHARS(v
, scm_must_malloc((long)(nlen
*sizeof(SCM_BIGDIG
)), s_bignum
));
721 SCM_SETNUMDIGS(v
, nlen
, sign
?scm_tc16_bigneg
:scm_tc16_bigpos
);
732 unsigned long num
= 0;
733 SCM_BIGDIG
*tmp
= SCM_BDIGITS(b
);
734 while (l
--) num
= SCM_BIGUP(num
) + tmp
[l
];
735 if (SCM_TYP16(b
)==scm_tc16_bigpos
) {
736 if SCM_POSFIXABLE(num
) return SCM_MAKINUM(num
);
738 else if SCM_UNEGFIXABLE(num
) return SCM_MAKINUM(-num
);
743 char s_adjbig
[] = "scm_adjbig";
750 scm_sizet nsiz
= nlen
;
751 if (((nsiz
<< 16) >> 16) != nlen
)
752 scm_wta (scm_ulong2num (nsiz
), (char *)SCM_NALLOC
, s_adjbig
);
758 scm_must_realloc((char *)SCM_CHARS(b
),
759 (long)(SCM_NUMDIGS(b
)*sizeof(SCM_BIGDIG
)),
760 (long)(nsiz
*sizeof(SCM_BIGDIG
)), s_adjbig
));
762 SCM_SETCHARS (b
, digits
);
763 SCM_SETNUMDIGS (b
, nsiz
, SCM_TYP16(b
));
776 scm_sizet nlen
= SCM_NUMDIGS(b
);
778 int nlen
= SCM_NUMDIGS(b
); /* unsigned nlen breaks on Cray when nlen => 0 */
780 SCM_BIGDIG
*zds
= SCM_BDIGITS(b
);
781 while (nlen
-- && !zds
[nlen
]); nlen
++;
782 if (nlen
* SCM_BITSPERDIG
/SCM_CHAR_BIT
<= sizeof(SCM
))
783 if SCM_INUMP(b
= scm_big2inum(b
, (scm_sizet
)nlen
)) return b
;
784 if (SCM_NUMDIGS(b
)==nlen
) return b
;
785 return scm_adjbig(b
, (scm_sizet
)nlen
);
795 scm_sizet i
= SCM_NUMDIGS(b
);
796 SCM ans
= scm_mkbig(i
, sign
);
797 SCM_BIGDIG
*src
= SCM_BDIGITS(b
), *dst
= SCM_BDIGITS(ans
);
798 while (i
--) dst
[i
] = src
[i
];
810 SCM ans
= scm_mkbig(SCM_DIGSPERLONG
, n
<0);
811 digits
= SCM_BDIGITS(ans
);
813 while (i
< SCM_DIGSPERLONG
) {
814 digits
[i
++] = SCM_BIGLO(n
);
815 n
= SCM_BIGDN((unsigned long)n
);
834 if ((long long)tn
== n
)
835 return scm_long2big (tn
);
841 for (tn
= n
, n_digits
= 0;
843 ++n_digits
, tn
= SCM_BIGDN ((ulong_long
)tn
))
848 ans
= scm_mkbig(n_digits
, n
<0);
849 digits
= SCM_BDIGITS(ans
);
852 while (i
< n_digits
) {
853 digits
[i
++] = SCM_BIGLO(n
);
854 n
= SCM_BIGDN((ulong_long
)n
);
870 ans
= scm_mkbig(2 * SCM_DIGSPERLONG
, 0);
871 digits
= SCM_BDIGITS(ans
);
874 for (i
= 0; i
< SCM_DIGSPERLONG
; ++i
)
876 digits
[i
] = SCM_BIGLO(n
);
877 n
= SCM_BIGDN((unsigned long)n
);
880 for (i
= 0; i
< SCM_DIGSPERLONG
; ++i
)
882 digits
[i
+ SCM_DIGSPERLONG
] = SCM_BIGLO(n
);
883 n
= SCM_BIGDN((unsigned long)n
);
896 SCM ans
= scm_mkbig(SCM_DIGSPERLONG
, 0);
897 digits
= SCM_BDIGITS(ans
);
898 while (i
< SCM_DIGSPERLONG
) {
899 digits
[i
++] = SCM_BIGLO(n
);
912 int xsign
= SCM_BIGSIGN(x
);
913 int ysign
= SCM_BIGSIGN(y
);
914 scm_sizet xlen
, ylen
;
916 /* Look at the signs, first. */
917 if (ysign
< xsign
) return 1;
918 if (ysign
> xsign
) return -1;
920 /* They're the same sign, so see which one has more digits. Note
921 that, if they are negative, the longer number is the lesser. */
922 ylen
= SCM_NUMDIGS(y
);
923 xlen
= SCM_NUMDIGS(x
);
925 return (xsign
) ? -1 : 1;
926 if (ylen
< xlen
) return (xsign
) ? 1 : -1;
928 /* They have the same number of digits, so find the most significant
929 digit where they differ. */
933 if (SCM_BDIGITS (y
)[xlen
] != SCM_BDIGITS (x
)[xlen
])
934 /* Make the discrimination based on the digit that differs. */
935 return (SCM_BDIGITS(y
)[xlen
] > SCM_BDIGITS(x
)[xlen
]) ?
936 (xsign
? -1 : 1) : (xsign
? 1 : -1);
939 /* The numbers are identical. */
943 #ifndef SCM_DIGSTOOBIG
952 SCM_BIGDIG bd
[SCM_DIGSPERLONG
];
956 while (i
< SCM_DIGSPERLONG
) {p
.bd
[i
++] = SCM_BIGLO(x
); x
= SCM_BIGDN(x
);}
957 /* p.bd[0] = SCM_BIGLO(x); p.bd[1] = SCM_BIGDN(x); */
965 scm_longdigs(x
, digs
)
971 while (i
< SCM_DIGSPERLONG
) {digs
[i
++] = SCM_BIGLO(x
); x
= SCM_BIGDN(x
);}
978 scm_addbig(x
, nx
, xsgn
, bigy
, sgny
)
985 /* Assumes nx <= SCM_NUMDIGS(bigy) */
986 /* Assumes xsgn and sgny scm_equal either 0 or 0x0100 */
988 scm_sizet i
= 0, ny
= SCM_NUMDIGS(bigy
);
989 SCM z
= scm_copybig(bigy
, SCM_BIGSIGN(bigy
) ^ sgny
);
990 SCM_BIGDIG
*zds
= SCM_BDIGITS(z
);
991 if (xsgn
^ SCM_BIGSIGN(z
)) {
993 num
+= (long) zds
[i
] - x
[i
];
994 if (num
< 0) {zds
[i
] = num
+ SCM_BIGRAD
; num
= -1;}
995 else {zds
[i
] = SCM_BIGLO(num
); num
= 0;}
999 SCM_SETCAR (z
, SCM_CAR (z
) ^ 0x0100);
1001 num
+= (SCM_BIGRAD
-1) - zds
[i
];
1002 zds
[i
++] = SCM_BIGLO(num
);
1003 num
= SCM_BIGDN(num
);
1006 else while (i
< ny
) {
1008 if (num
< 0) {zds
[i
++] = num
+ SCM_BIGRAD
; num
= -1;}
1009 else {zds
[i
++] = SCM_BIGLO(num
); num
= 0;}
1013 num
+= (long) zds
[i
] + x
[i
];
1014 zds
[i
++] = SCM_BIGLO(num
);
1015 num
= SCM_BIGDN(num
);
1020 zds
[i
++] = SCM_BIGLO(num
);
1021 num
= SCM_BIGDN(num
);
1024 if (num
) {z
= scm_adjbig(z
, ny
+1); SCM_BDIGITS(z
)[ny
] = num
; return z
;}
1026 return scm_normbig(z
);
1031 scm_mulbig(x
, nx
, y
, ny
, sgn
)
1038 scm_sizet i
= 0, j
= nx
+ ny
;
1039 unsigned long n
= 0;
1040 SCM z
= scm_mkbig(j
, sgn
);
1041 SCM_BIGDIG
*zds
= SCM_BDIGITS(z
);
1042 while (j
--) zds
[j
] = 0;
1047 n
+= zds
[i
+ j
] + ((unsigned long) x
[i
] * y
[j
]);
1048 zds
[i
+ j
++] = SCM_BIGLO(n
);
1051 if (n
) {zds
[i
+ j
] = n
; n
= 0;}
1054 return scm_normbig(z
);
1058 /* Sun's compiler complains about the fact that this function has an
1059 ANSI prototype in numbers.h, but a K&R declaration here, and the
1060 two specify different promotions for the third argument. I'm going
1061 to turn this into an ANSI declaration, and see if anyone complains
1062 about it not being K&R. */
1065 scm_divbigdig(SCM_BIGDIG
*ds
,
1069 register unsigned long t2
= 0;
1071 t2
= SCM_BIGUP(t2
) + ds
[h
];
1081 scm_divbigint(x
, z
, sgn
, mode
)
1088 if (z
< SCM_BIGRAD
) {
1089 register unsigned long t2
= 0;
1090 register SCM_BIGDIG
*ds
= SCM_BDIGITS(x
);
1091 scm_sizet nd
= SCM_NUMDIGS(x
);
1092 while(nd
--) t2
= (SCM_BIGUP(t2
) + ds
[nd
]) % z
;
1093 if (mode
&& t2
) t2
= z
- t2
;
1094 return SCM_MAKINUM(sgn
? -t2
: t2
);
1097 #ifndef SCM_DIGSTOOBIG
1098 unsigned long t2
= scm_pseudolong(z
);
1099 return scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), (SCM_BIGDIG
*)&t2
,
1100 SCM_DIGSPERLONG
, sgn
, mode
);
1102 SCM_BIGDIG t2
[SCM_DIGSPERLONG
];
1103 scm_longdigs(z
, t2
);
1104 return scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), t2
, SCM_DIGSPERLONG
, sgn
, mode
);
1111 scm_divbigbig(x
, nx
, y
, ny
, sgn
, modes
)
1119 /* modes description
1123 3 quotient but returns 0 if division is not exact. */
1124 scm_sizet i
= 0, j
= 0;
1126 unsigned long t2
= 0;
1128 SCM_BIGDIG d
= 0, qhat
, *zds
, *yds
;
1129 /* algorithm requires nx >= ny */
1132 case 0: /* remainder -- just return x */
1133 z
= scm_mkbig(nx
, sgn
); zds
= SCM_BDIGITS(z
);
1134 do {zds
[i
] = x
[i
];} while (++i
< nx
);
1136 case 1: /* scm_modulo -- return y-x */
1137 z
= scm_mkbig(ny
, sgn
); zds
= SCM_BDIGITS(z
);
1139 num
+= (long) y
[i
] - x
[i
];
1140 if (num
< 0) {zds
[i
] = num
+ SCM_BIGRAD
; num
= -1;}
1141 else {zds
[i
] = num
; num
= 0;}
1145 if (num
< 0) {zds
[i
++] = num
+ SCM_BIGRAD
; num
= -1;}
1146 else {zds
[i
++] = num
; num
= 0;}
1149 case 2: return SCM_INUM0
; /* quotient is zero */
1150 case 3: return 0; /* the division is not exact */
1153 z
= scm_mkbig(nx
==ny
? nx
+2 : nx
+1, sgn
); zds
= SCM_BDIGITS(z
);
1154 if (nx
==ny
) zds
[nx
+1] = 0;
1155 while(!y
[ny
-1]) ny
--; /* in case y came in as a psuedolong */
1156 if (y
[ny
-1] < (SCM_BIGRAD
>>1)) { /* normalize operands */
1157 d
= SCM_BIGRAD
/(y
[ny
-1]+1);
1158 newy
= scm_mkbig(ny
, 0); yds
= SCM_BDIGITS(newy
);
1160 {t2
+= (unsigned long) y
[j
]*d
; yds
[j
++] = SCM_BIGLO(t2
); t2
= SCM_BIGDN(t2
);}
1161 y
= yds
; j
= 0; t2
= 0;
1163 {t2
+= (unsigned long) x
[j
]*d
; zds
[j
++] = SCM_BIGLO(t2
); t2
= SCM_BIGDN(t2
);}
1166 else {zds
[j
= nx
] = 0; while (j
--) zds
[j
] = x
[j
];}
1167 j
= nx
==ny
? nx
+1 : nx
; /* dividend needs more digits than divisor */
1168 do { /* loop over digits of quotient */
1169 if (zds
[j
]==y
[ny
-1]) qhat
= SCM_BIGRAD
-1;
1170 else qhat
= (SCM_BIGUP(zds
[j
]) + zds
[j
-1])/y
[ny
-1];
1171 if (!qhat
) continue;
1172 i
= 0; num
= 0; t2
= 0;
1173 do { /* multiply and subtract */
1174 t2
+= (unsigned long) y
[i
] * qhat
;
1175 num
+= zds
[j
- ny
+ i
] - SCM_BIGLO(t2
);
1176 if (num
< 0) {zds
[j
- ny
+ i
] = num
+ SCM_BIGRAD
; num
= -1;}
1177 else {zds
[j
- ny
+ i
] = num
; num
= 0;}
1180 num
+= zds
[j
- ny
+ i
] - t2
; /* borrow from high digit; don't update */
1181 while (num
) { /* "add back" required */
1182 i
= 0; num
= 0; qhat
--;
1184 num
+= (long) zds
[j
- ny
+ i
] + y
[i
];
1185 zds
[j
- ny
+ i
] = SCM_BIGLO(num
);
1186 num
= SCM_BIGDN(num
);
1190 if (modes
& 2) zds
[j
] = qhat
;
1191 } while (--j
>= ny
);
1193 case 3: /* check that remainder==0 */
1194 for(j
= ny
;j
&& !zds
[j
-1];--j
) ; if (j
) return 0;
1195 case 2: /* move quotient down in z */
1196 j
= (nx
==ny
? nx
+2 : nx
+1) - ny
;
1197 for (i
= 0;i
< j
;i
++) zds
[i
] = zds
[i
+ny
];
1200 case 1: /* subtract for scm_modulo */
1201 i
= 0; num
= 0; j
= 0;
1202 do {num
+= y
[i
] - zds
[i
];
1204 if (num
< 0) {zds
[i
] = num
+ SCM_BIGRAD
; num
= -1;}
1205 else {zds
[i
] = num
; num
= 0;}
1207 if (!j
) return SCM_INUM0
;
1208 case 0: /* just normalize remainder */
1209 if (d
) scm_divbigdig(zds
, ny
, d
);
1212 for(j
= ny
;j
&& !zds
[j
-1];--j
) ;
1213 if (j
* SCM_BITSPERDIG
<= sizeof(SCM
)*SCM_CHAR_BIT
)
1214 if SCM_INUMP(z
= scm_big2inum(z
, j
)) return z
;
1215 return scm_adjbig(z
, j
);
1223 /*** NUMBERS -> STRINGS ***/
1226 static double fx
[] = {0.0, 5e-1, 5e-2, 5e-3, 5e-4, 5e-5,
1227 5e-6, 5e-7, 5e-8, 5e-9, 5e-10,
1228 5e-11,5e-12,5e-13,5e-14,5e-15,
1229 5e-16,5e-17,5e-18,5e-19,5e-20};
1234 static scm_sizet idbl2str
SCM_P ((double f
, char *a
));
1241 int efmt
, dpt
, d
, i
, wp
= scm_dblprec
;
1245 if (f
== 0.0) goto zero
; /*{a[0]='0'; a[1]='.'; a[2]='0'; return 3;}*/
1246 if (f
< 0.0) {f
= -f
;a
[ch
++]='-';}
1251 if (ch
== 0) a
[ch
++]='+';
1252 funny
: a
[ch
++]='#'; a
[ch
++]='.'; a
[ch
++]='#'; return ch
;
1254 # ifdef DBL_MIN_10_EXP /* Prevent unnormalized values, as from
1255 make-uniform-vector, from causing infinite loops. */
1256 while (f
< 1.0) {f
*= 10.0; if (exp
-- < DBL_MIN_10_EXP
) goto funny
;}
1257 while (f
> 10.0) {f
*= 0.10; if (exp
++ > DBL_MAX_10_EXP
) goto funny
;}
1259 while (f
< 1.0) {f
*= 10.0; exp
--;}
1260 while (f
> 10.0) {f
/= 10.0; exp
++;}
1262 if (f
+fx
[wp
] >= 10.0) {f
= 1.0; exp
++;}
1269 efmt
= (exp
< -3) || (exp
> wp
+2);
1277 while (++dpt
) a
[ch
++] = '0';
1290 if (f
< fx
[wp
]) break;
1291 if (f
+fx
[wp
] >= 1.0) {
1296 if (!(--dpt
)) a
[ch
++] = '.';
1302 if ((dpt
> 4) && (exp
> 6))
1304 d
= (a
[0]=='-'?2:1);
1305 for (i
= ch
++; i
> d
; i
--)
1313 while (--dpt
) a
[ch
++] = '0';
1317 if (a
[ch
-1]=='.') a
[ch
++]='0'; /* trailing zero */
1324 for (i
= 10; i
<= exp
; i
*= 10);
1325 for (i
/= 10; i
; i
/= 10) {
1326 a
[ch
++] = exp
/i
+ '0';
1334 static scm_sizet iflo2str
SCM_P ((SCM flt
, char *str
));
1343 if SCM_SINGP(flt
) i
= idbl2str(SCM_FLO(flt
), str
);
1346 i
= idbl2str(SCM_REAL(flt
), str
);
1348 if(0 <= SCM_IMAG(flt
)) /* jeh */
1349 str
[i
++] = '+'; /* jeh */
1350 i
+= idbl2str(SCM_IMAG(flt
), &str
[i
]);
1355 #endif /* SCM_FLOATS */
1359 scm_iint2str(num
, rad
, p
)
1365 register int i
= 1, d
;
1366 register long n
= num
;
1367 if (n
< 0) {n
= -n
; i
++;}
1368 for (n
/= rad
;n
> 0;n
/= rad
) i
++;
1371 if (n
< 0) {n
= -n
; *p
++ = '-'; i
--;}
1375 p
[i
] = d
+ ((d
< 10) ? '0' : 'a' - 10);
1383 static SCM big2str
SCM_P ((SCM b
, register unsigned int radix
));
1388 register unsigned int radix
;
1390 SCM t
= scm_copybig(b
, 0); /* sign of temp doesn't matter */
1391 register SCM_BIGDIG
*ds
= SCM_BDIGITS(t
);
1392 scm_sizet i
= SCM_NUMDIGS(t
);
1393 scm_sizet j
= radix
==16 ? (SCM_BITSPERDIG
*i
)/4+2
1394 : radix
>= 10 ? (SCM_BITSPERDIG
*i
*241L)/800+2
1395 : (SCM_BITSPERDIG
*i
)+2;
1397 scm_sizet radct
= 0;
1398 scm_sizet ch
; /* jeh */
1399 SCM_BIGDIG radpow
= 1, radmod
= 0;
1400 SCM ss
= scm_makstr((long)j
, 0);
1401 char *s
= SCM_CHARS(ss
), c
;
1402 while ((long) radpow
* radix
< SCM_BIGRAD
) {
1406 s
[0] = scm_tc16_bigneg
==SCM_TYP16(b
) ? '-' : '+';
1407 while ((i
|| radmod
) && j
) {
1409 radmod
= (SCM_BIGDIG
)scm_divbigdig(ds
, i
, radpow
);
1413 c
= radmod
% radix
; radmod
/= radix
; k
--;
1414 s
[--j
] = c
< 10 ? c
+ '0' : c
+ 'a' - 10;
1416 ch
= s
[0] == '-' ? 1 : 0; /* jeh */
1417 if (ch
< j
) { /* jeh */
1418 for(i
= j
;j
< SCM_LENGTH(ss
);j
++) s
[ch
+j
-i
] = s
[j
]; /* jeh */
1419 scm_vector_set_length_x(ss
, (SCM
)SCM_MAKINUM(ch
+SCM_LENGTH(ss
)-i
)); /* jeh */
1422 return scm_return_first (ss
, t
);
1427 SCM_PROC(s_number_to_string
, "number->string", 1, 1, 0, scm_number_to_string
);
1430 scm_number_to_string(x
, radix
)
1434 if SCM_UNBNDP(radix
) radix
=SCM_MAKINUM(10L);
1435 else SCM_ASSERT(SCM_INUMP(radix
), radix
, SCM_ARG2
, s_number_to_string
);
1438 char num_buf
[SCM_FLOBUFLEN
];
1440 SCM_ASRTGO(SCM_NIMP(x
), badx
);
1441 if SCM_BIGP(x
) return big2str(x
, (unsigned int)SCM_INUM(radix
));
1443 if (!(SCM_INEXP(x
)))
1444 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_number_to_string
);
1447 SCM_ASSERT(SCM_NIMP(x
) && SCM_INEXP(x
), x
, SCM_ARG1
, s_number_to_string
);
1449 return scm_makfromstr(num_buf
, iflo2str(x
, num_buf
), 0);
1454 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_number_to_string
);
1455 return big2str(x
, (unsigned int)SCM_INUM(radix
));
1458 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_number_to_string
);
1462 char num_buf
[SCM_INTBUFLEN
];
1463 return scm_makfromstr(num_buf
,
1464 scm_iint2str(SCM_INUM(x
), (int)SCM_INUM(radix
), num_buf
), 0);
1469 /* These print routines are stubbed here so that scm_repl.c doesn't need
1470 SCM_FLOATS or SCM_BIGDIGs conditionals */
1473 scm_floprint(sexp
, port
, pstate
)
1476 scm_print_state
*pstate
;
1479 char num_buf
[SCM_FLOBUFLEN
];
1480 scm_lfwrite (num_buf
, iflo2str(sexp
, num_buf
), port
);
1482 scm_ipruk("float", sexp
, port
);
1490 scm_bigprint(exp
, port
, pstate
)
1493 scm_print_state
*pstate
;
1496 exp
= big2str(exp
, (unsigned int)10);
1497 scm_lfwrite (SCM_CHARS(exp
), (scm_sizet
)SCM_LENGTH(exp
), port
);
1499 scm_ipruk("bignum", exp
, port
);
1503 /*** END nums->strs ***/
1505 /*** STRINGS -> NUMBERS ***/
1507 static SCM scm_small_istr2int
SCM_P ((char *str
, long len
, long radix
));
1510 scm_small_istr2int(str
, len
, radix
)
1515 register long n
= 0, ln
;
1519 if (0 >= len
) return SCM_BOOL_F
; /* zero scm_length */
1520 switch (*str
) { /* leading sign */
1521 case '-': lead_neg
= 1;
1522 case '+': if (++i
==len
) return SCM_BOOL_F
; /* bad if lone `+' or `-' */
1526 switch (c
= str
[i
++]) {
1530 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1533 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1536 if (c
>= radix
) return SCM_BOOL_F
; /* bad digit for radix */
1539 /* Negation is a workaround for HP700 cc bug */
1540 if (n
> ln
|| (-n
> -SCM_MOST_NEGATIVE_FIXNUM
)) goto ovfl
;
1543 return SCM_BOOL_F
; /* not a digit */
1546 if (!lead_neg
) if ((n
= -n
) > SCM_MOST_POSITIVE_FIXNUM
) goto ovfl
;
1547 return SCM_MAKINUM(n
);
1548 ovfl
: /* overflow scheme integer */
1555 scm_istr2int(str
, len
, radix
)
1561 register scm_sizet k
, blen
= 1;
1565 register SCM_BIGDIG
*ds
;
1566 register unsigned long t2
;
1568 if (0 >= len
) return SCM_BOOL_F
; /* zero scm_length */
1570 /* Short numbers we parse directly into an int, to avoid the overhead
1571 of creating a bignum. */
1573 return scm_small_istr2int (str
, len
, radix
);
1575 if (16==radix
) j
= 1+(4*len
*sizeof(char))/(SCM_BITSPERDIG
);
1576 else if (10 <= radix
)
1577 j
= 1+(84*len
*sizeof(char))/(SCM_BITSPERDIG
*25);
1578 else j
= 1+(len
*sizeof(char))/(SCM_BITSPERDIG
);
1579 switch (str
[0]) { /* leading sign */
1582 if (++i
==(unsigned) len
)
1583 return SCM_BOOL_F
; /* bad if lone `+' or `-' */
1585 res
= scm_mkbig(j
, '-'==str
[0]);
1586 ds
= SCM_BDIGITS(res
);
1587 for (k
= j
;k
--;) ds
[k
] = 0;
1589 switch (c
= str
[i
++]) {
1593 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1596 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1599 if (c
>= radix
) return SCM_BOOL_F
; /* bad digit for radix */
1604 /* printf("k = %d, blen = %d, t2 = %ld, ds[k] = %d\n", k, blen, t2, ds[k]);*/
1606 ds
[k
++] = SCM_BIGLO(t2
);
1610 scm_num_overflow ("bignum");
1611 if (t2
) {blen
++; goto moretodo
;}
1614 return SCM_BOOL_F
; /* not a digit */
1616 } while (i
< (unsigned) len
);
1617 if (blen
* SCM_BITSPERDIG
/SCM_CHAR_BIT
<= sizeof(SCM
))
1618 if SCM_INUMP(res
= scm_big2inum(res
, blen
)) return res
;
1619 if (j
==blen
) return res
;
1620 return scm_adjbig(res
, blen
);
1626 scm_istr2flo(str
, len
, radix
)
1631 register int c
, i
= 0;
1633 double res
= 0.0, tmp
= 0.0;
1638 if (i
>= len
) return SCM_BOOL_F
; /* zero scm_length */
1640 switch (*str
) { /* leading sign */
1641 case '-': lead_sgn
= -1.0; i
++; break;
1642 case '+': lead_sgn
= 1.0; i
++; break;
1643 default : lead_sgn
= 0.0;
1645 if (i
==len
) return SCM_BOOL_F
; /* bad if lone `+' or `-' */
1647 if (str
[i
]=='i' || str
[i
]=='I') { /* handle `+i' and `-i' */
1648 if (lead_sgn
==0.0) return SCM_BOOL_F
; /* must have leading sign */
1649 if (++i
< len
) return SCM_BOOL_F
; /* `i' not last character */
1650 return scm_makdbl(0.0, lead_sgn
);
1652 do { /* check initial digits */
1653 switch (c
= str
[i
]) {
1657 case 'D': case 'E': case 'F':
1658 if (radix
==10) goto out1
; /* must be exponent */
1659 case 'A': case 'B': case 'C':
1662 case 'd': case 'e': case 'f':
1663 if (radix
==10) goto out1
;
1664 case 'a': case 'b': case 'c':
1667 if (c
>= radix
) return SCM_BOOL_F
; /* bad digit for radix */
1668 res
= res
* radix
+ c
;
1669 flg
= 1; /* res is valid */
1674 } while (++i
< len
);
1677 /* if true, then we did see a digit above, and res is valid */
1678 if (i
==len
) goto done
;
1680 /* By here, must have seen a digit,
1681 or must have next char be a `.' with radix==10 */
1683 if (!(str
[i
]=='.' && radix
==10))
1686 while (str
[i
]=='#') { /* optional sharps */
1688 if (++i
==len
) goto done
;
1693 switch (c
= str
[i
]) {
1697 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1700 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1703 if (c
>= radix
) return SCM_BOOL_F
;
1704 tmp
= tmp
* radix
+ c
;
1711 if (tmp
==0.0) return SCM_BOOL_F
; /* `slash zero' not allowed */
1713 while (str
[i
]=='#') { /* optional sharps */
1715 if (++i
==len
) break;
1721 if (str
[i
]=='.') { /* decimal point notation */
1722 if (radix
!= 10) return SCM_BOOL_F
; /* must be radix 10 */
1724 switch (c
= str
[i
]) {
1727 res
= res
*10.0 + c
-'0';
1735 if (!flg
) return SCM_BOOL_F
; /* no digits before or after decimal point */
1736 if (i
==len
) goto adjust
;
1737 while (str
[i
]=='#') { /* ignore remaining sharps */
1738 if (++i
==len
) goto adjust
;
1742 switch (str
[i
]) { /* exponent */
1747 case 's': case 'S': {
1748 int expsgn
= 1, expon
= 0;
1749 if (radix
!= 10) return SCM_BOOL_F
; /* only in radix 10 */
1750 if (++i
==len
) return SCM_BOOL_F
; /* bad exponent */
1752 case '-': expsgn
=(-1);
1753 case '+': if (++i
==len
) return SCM_BOOL_F
; /* bad exponent */
1755 if (str
[i
] < '0' || str
[i
] > '9') return SCM_BOOL_F
; /* bad exponent */
1757 switch (c
= str
[i
]) {
1759 expon
= expon
*10 + c
-'0';
1760 if (expon
> MAXEXP
) return SCM_BOOL_F
; /* exponent too large */
1765 } while (++i
< len
);
1767 point
+= expsgn
*expon
;
1773 while (point
--) res
*= 10.0;
1776 while (point
++) res
*= 0.1;
1778 while (point
++) res
/= 10.0;
1782 /* at this point, we have a legitimate floating point result */
1783 if (lead_sgn
==-1.0) res
= -res
;
1784 if (i
==len
) return scm_makdbl(res
, 0.0);
1786 if (str
[i
]=='i' || str
[i
]=='I') { /* pure imaginary number */
1787 if (lead_sgn
==0.0) return SCM_BOOL_F
; /* must have leading sign */
1788 if (++i
< len
) return SCM_BOOL_F
; /* `i' not last character */
1789 return scm_makdbl(0.0, res
);
1793 case '-': lead_sgn
= -1.0; break;
1794 case '+': lead_sgn
= 1.0; break;
1795 case '@': { /* polar input for complex number */
1796 /* get a `real' for scm_angle */
1797 second
= scm_istr2flo(&str
[i
], (long)(len
-i
), radix
);
1798 if (!(SCM_INEXP(second
))) return SCM_BOOL_F
; /* not `real' */
1799 if (SCM_CPLXP(second
)) return SCM_BOOL_F
; /* not `real' */
1800 tmp
= SCM_REALPART(second
);
1801 return scm_makdbl(res
*cos(tmp
), res
*sin(tmp
));
1803 default: return SCM_BOOL_F
;
1806 /* at this point, last char must be `i' */
1807 if (str
[len
-1] != 'i' && str
[len
-1] != 'I') return SCM_BOOL_F
;
1808 /* handles `x+i' and `x-i' */
1809 if (i
==(len
-1)) return scm_makdbl(res
, lead_sgn
);
1810 /* get a `ureal' for complex part */
1811 second
= scm_istr2flo(&str
[i
], (long)((len
-i
)-1), radix
);
1812 if (!(SCM_INEXP(second
))) return SCM_BOOL_F
; /* not `ureal' */
1813 if (SCM_CPLXP(second
)) return SCM_BOOL_F
; /* not `ureal' */
1814 tmp
= SCM_REALPART(second
);
1815 if (tmp
< 0.0) return SCM_BOOL_F
; /* not `ureal' */
1816 return scm_makdbl(res
, (lead_sgn
*tmp
));
1818 #endif /* SCM_FLOATS */
1823 scm_istring2number(str
, len
, radix
)
1830 char ex_p
= 0, rx_p
= 0; /* Only allow 1 exactness and 1 radix prefix */
1833 if (*str
=='+' || *str
=='-') /* Catches lone `+' and `-' for speed */
1836 while ((len
-i
) >= 2 && str
[i
]=='#' && ++i
)
1838 case 'b': case 'B': if (rx_p
++) return SCM_BOOL_F
; radix
= 2; break;
1839 case 'o': case 'O': if (rx_p
++) return SCM_BOOL_F
; radix
= 8; break;
1840 case 'd': case 'D': if (rx_p
++) return SCM_BOOL_F
; radix
= 10; break;
1841 case 'x': case 'X': if (rx_p
++) return SCM_BOOL_F
; radix
= 16; break;
1842 case 'i': case 'I': if (ex_p
++) return SCM_BOOL_F
; ex
= 2; break;
1843 case 'e': case 'E': if (ex_p
++) return SCM_BOOL_F
; ex
= 1; break;
1844 default: return SCM_BOOL_F
;
1849 return scm_istr2int(&str
[i
], len
-i
, radix
);
1851 res
= scm_istr2int(&str
[i
], len
-i
, radix
);
1852 if SCM_NFALSEP(res
) return res
;
1854 case 2: return scm_istr2flo(&str
[i
], len
-i
, radix
);
1861 SCM_PROC(s_string_to_number
, "string->number", 1, 1, 0, scm_string_to_number
);
1864 scm_string_to_number(str
, radix
)
1869 if SCM_UNBNDP(radix
) radix
=SCM_MAKINUM(10L);
1870 else SCM_ASSERT(SCM_INUMP(radix
), radix
, SCM_ARG2
, s_string_to_number
);
1871 SCM_ASSERT(SCM_NIMP(str
) && SCM_ROSTRINGP(str
), str
, SCM_ARG1
, s_string_to_number
);
1872 answer
= scm_istring2number(SCM_ROCHARS(str
), SCM_ROLENGTH(str
), SCM_INUM(radix
));
1873 return scm_return_first (answer
, str
);
1875 /*** END strs->nums ***/
1885 if ((y
==0.0) && (x
==0.0)) return scm_flo0
;
1891 # ifndef SCM_SINGLESONLY
1892 if ((-FLTMAX
< x
) && (x
< FLTMAX
) && (fx
==x
))
1895 SCM_SETCAR (z
, scm_tc_flo
);
1900 # endif/* def SCM_SINGLES */
1901 SCM_SETCDR (z
, (SCM
)scm_must_malloc(1L*sizeof(double), "real"));
1902 SCM_SETCAR (z
, scm_tc_dblr
);
1905 SCM_SETCDR (z
, (SCM
)scm_must_malloc(2L*sizeof(double), "complex"));
1906 SCM_SETCAR (z
, scm_tc_dblc
);
1923 if (0==scm_bigcomp(x
, y
)) return SCM_BOOL_T
;
1936 if (SCM_REALPART(x
) != SCM_REALPART(y
)) return SCM_BOOL_F
;
1937 if (!(SCM_CPLXP(x
) && (SCM_IMAG(x
) != SCM_IMAG(y
)))) return SCM_BOOL_T
;
1945 SCM_PROC(s_number_p
, "number?", 1, 0, 0, scm_number_p
);
1946 SCM_PROC(s_complex_p
, "complex?", 1, 0, 0, scm_number_p
);
1952 if SCM_INUMP(x
) return SCM_BOOL_T
;
1954 if (SCM_NIMP(x
) && SCM_NUMP(x
)) return SCM_BOOL_T
;
1957 if (SCM_NIMP(x
) && SCM_NUMP(x
)) return SCM_BOOL_T
;
1966 SCM_PROC(s_real_p
, "real?", 1, 0, 0, scm_real_p
);
1967 SCM_PROC(s_rational_p
, "rational?", 1, 0, 0, scm_real_p
);
1988 SCM_PROC(s_int_p
, "integer?", 1, 0, 0, scm_integer_p
);
1995 if SCM_INUMP(x
) return SCM_BOOL_T
;
1996 if SCM_IMP(x
) return SCM_BOOL_F
;
1998 if SCM_BIGP(x
) return SCM_BOOL_T
;
2000 if (!SCM_INEXP(x
)) return SCM_BOOL_F
;
2001 if (SCM_CPLXP(x
)) return SCM_BOOL_F
;
2002 r
= SCM_REALPART(x
);
2003 if (r
==floor(r
)) return SCM_BOOL_T
;
2009 #endif /* SCM_FLOATS */
2011 SCM_PROC(s_inexact_p
, "inexact?", 1, 0, 0, scm_inexact_p
);
2018 if (SCM_NIMP(x
) && SCM_INEXP(x
)) return SCM_BOOL_T
;
2026 SCM_PROC1 (s_eq_p
, "=", scm_tc7_rpsubr
, scm_num_eq_p
);
2039 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_eq_p
);
2042 if SCM_INUMP(y
) return SCM_BOOL_F
;
2043 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2044 if SCM_BIGP(y
) return (0==scm_bigcomp(x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2045 SCM_ASRTGO(SCM_INEXP(y
), bady
);
2047 return (SCM_REALP(y
) && (scm_big2dbl(x
)==SCM_REALPART(y
))) ? SCM_BOOL_T
: SCM_BOOL_F
;
2049 SCM_ASRTGO(SCM_INEXP(x
), badx
);
2051 SCM_ASSERT(SCM_NIMP(x
) && SCM_INEXP(x
), x
, SCM_ARG1
, s_eq_p
);
2053 if SCM_INUMP(y
) {t
= x
; x
= y
; y
= t
; goto realint
;}
2055 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2056 if SCM_BIGP(y
) {t
= x
; x
= y
; y
= t
; goto bigreal
;}
2057 SCM_ASRTGO(SCM_INEXP(y
), bady
);
2059 SCM_ASRTGO(SCM_NIMP(y
) && SCM_INEXP(y
), bady
);
2061 if (SCM_REALPART(x
) != SCM_REALPART(y
)) return SCM_BOOL_F
;
2063 return (SCM_CPLXP(y
) && (SCM_IMAG(x
)==SCM_IMAG(y
))) ? SCM_BOOL_T
: SCM_BOOL_F
;
2064 return SCM_CPLXP(y
) ? SCM_BOOL_F
: SCM_BOOL_T
;
2068 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2069 if SCM_BIGP(y
) return SCM_BOOL_F
;
2071 if (!(SCM_INEXP(y
)))
2072 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_eq_p
);
2076 if (!(SCM_NIMP(y
) && SCM_INEXP(y
)))
2077 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_eq_p
);
2081 return (SCM_REALP(y
) && (((double)SCM_INUM(x
))==SCM_REALPART(y
))) ? SCM_BOOL_T
: SCM_BOOL_F
;
2086 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_eq_p
);
2087 if SCM_INUMP(y
) return SCM_BOOL_F
;
2088 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
2089 return (0==scm_bigcomp(x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2093 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
2094 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_eq_p
);
2099 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_eq_p
);
2100 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_eq_p
);
2103 return ((long)x
==(long)y
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2108 SCM_PROC1 (s_less_p
, "<", scm_tc7_rpsubr
, scm_less_p
);
2120 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_less_p
);
2123 if SCM_INUMP(y
) return SCM_BIGSIGN(x
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2124 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2125 if SCM_BIGP(y
) return (1==scm_bigcomp(x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2126 SCM_ASRTGO(SCM_REALP(y
), bady
);
2127 return (scm_big2dbl(x
) < SCM_REALPART(y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2129 SCM_ASRTGO(SCM_REALP(x
), badx
);
2131 SCM_ASSERT(SCM_NIMP(x
) && SCM_REALP(x
), x
, SCM_ARG1
, s_less_p
);
2134 return (SCM_REALPART(x
) < ((double)SCM_INUM(y
))) ? SCM_BOOL_T
: SCM_BOOL_F
;
2136 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2137 if SCM_BIGP(y
) return (SCM_REALPART(x
) < scm_big2dbl(y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2138 SCM_ASRTGO(SCM_REALP(y
), bady
);
2140 SCM_ASRTGO(SCM_NIMP(y
) && SCM_REALP(y
), bady
);
2142 return (SCM_REALPART(x
) < SCM_REALPART(y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2146 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2147 if SCM_BIGP(y
) return SCM_BIGSIGN(y
) ? SCM_BOOL_F
: SCM_BOOL_T
;
2149 if (!(SCM_REALP(y
)))
2150 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_less_p
);
2154 if (!(SCM_NIMP(y
) && SCM_REALP(y
)))
2155 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_less_p
);
2158 return (((double)SCM_INUM(x
)) < SCM_REALPART(y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2163 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_less_p
);
2164 if SCM_INUMP(y
) return SCM_BIGSIGN(x
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2165 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
2166 return (1==scm_bigcomp(x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2170 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
2171 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_less_p
);
2173 return SCM_BIGSIGN(y
) ? SCM_BOOL_F
: SCM_BOOL_T
;
2176 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_less_p
);
2177 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_less_p
);
2180 return ((long)x
< (long)y
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2184 SCM_PROC1 (s_gr_p
, ">", scm_tc7_rpsubr
, scm_gr_p
);
2191 return scm_less_p(y
, x
);
2196 SCM_PROC1 (s_leq_p
, "<=", scm_tc7_rpsubr
, scm_leq_p
);
2203 return SCM_BOOL_NOT(scm_less_p(y
, x
));
2208 SCM_PROC1 (s_geq_p
, ">=", scm_tc7_rpsubr
, scm_geq_p
);
2215 return SCM_BOOL_NOT(scm_less_p(x
, y
));
2220 SCM_PROC(s_zero_p
, "zero?", 1, 0, 0, scm_zero_p
);
2229 SCM_ASRTGO(SCM_NIMP(z
), badz
);
2230 if SCM_BIGP(z
) return SCM_BOOL_F
;
2232 if (!(SCM_INEXP(z
)))
2233 badz
: scm_wta(z
, (char *)SCM_ARG1
, s_zero_p
);
2236 SCM_ASSERT(SCM_NIMP(z
) && SCM_INEXP(z
), z
, SCM_ARG1
, s_zero_p
);
2238 return (z
==scm_flo0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2243 SCM_ASSERT(SCM_NIMP(z
) && SCM_BIGP(z
), z
, SCM_ARG1
, s_zero_p
);
2247 SCM_ASSERT(SCM_INUMP(z
), z
, SCM_ARG1
, s_zero_p
);
2250 return (z
==SCM_INUM0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2255 SCM_PROC(s_positive_p
, "positive?", 1, 0, 0, scm_positive_p
);
2264 SCM_ASRTGO(SCM_NIMP(x
), badx
);
2265 if SCM_BIGP(x
) return SCM_TYP16(x
)==scm_tc16_bigpos
? SCM_BOOL_T
: SCM_BOOL_F
;
2267 if (!(SCM_REALP(x
)))
2268 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_positive_p
);
2271 SCM_ASSERT(SCM_NIMP(x
) && SCM_REALP(x
), x
, SCM_ARG1
, s_positive_p
);
2273 return (SCM_REALPART(x
) > 0.0) ? SCM_BOOL_T
: SCM_BOOL_F
;
2278 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_positive_p
);
2279 return SCM_TYP16(x
)==scm_tc16_bigpos
? SCM_BOOL_T
: SCM_BOOL_F
;
2282 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_positive_p
);
2285 return (x
> SCM_INUM0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2290 SCM_PROC(s_negative_p
, "negative?", 1, 0, 0, scm_negative_p
);
2299 SCM_ASRTGO(SCM_NIMP(x
), badx
);
2300 if SCM_BIGP(x
) return SCM_TYP16(x
)==scm_tc16_bigpos
? SCM_BOOL_F
: SCM_BOOL_T
;
2302 if (!(SCM_REALP(x
)))
2303 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_negative_p
);
2306 SCM_ASSERT(SCM_NIMP(x
) && SCM_REALP(x
), x
, SCM_ARG1
, s_negative_p
);
2308 return (SCM_REALPART(x
) < 0.0) ? SCM_BOOL_T
: SCM_BOOL_F
;
2313 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_negative_p
);
2314 return (SCM_TYP16(x
)==scm_tc16_bigneg
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2317 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_negative_p
);
2320 return (x
< SCM_INUM0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2324 SCM_PROC1 (s_max
, "max", scm_tc7_asubr
, scm_max
);
2336 if (!(SCM_NUMBERP(x
)))
2337 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_max
);
2344 SCM_ASRTGO(SCM_NIMP(x
), badx
);
2346 if SCM_INUMP(y
) return SCM_BIGSIGN(x
) ? y
: x
;
2347 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2348 if SCM_BIGP(y
) return (1==scm_bigcomp(x
, y
)) ? y
: x
;
2349 SCM_ASRTGO(SCM_REALP(y
), bady
);
2351 return (z
< SCM_REALPART(y
)) ? y
: scm_makdbl(z
, 0.0);
2353 SCM_ASRTGO(SCM_REALP(x
), badx
);
2355 SCM_ASSERT(SCM_NIMP(x
) && SCM_REALP(x
), x
, SCM_ARG1
, s_max
);
2358 return (SCM_REALPART(x
) < (z
= SCM_INUM(y
))) ? scm_makdbl(z
, 0.0) : x
;
2360 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2362 return (SCM_REALPART(x
) < (z
= scm_big2dbl(y
))) ? scm_makdbl(z
, 0.0) : x
;
2363 SCM_ASRTGO(SCM_REALP(y
), bady
);
2365 SCM_ASRTGO(SCM_NIMP(y
) && SCM_REALP(y
), bady
);
2367 return (SCM_REALPART(x
) < SCM_REALPART(y
)) ? y
: x
;
2371 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2372 if SCM_BIGP(y
) return SCM_BIGSIGN(y
) ? x
: y
;
2374 if (!(SCM_REALP(y
)))
2375 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_max
);
2379 if (!(SCM_NIMP(y
) && SCM_REALP(y
)))
2380 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_max
);
2383 return ((z
= SCM_INUM(x
)) < SCM_REALPART(y
)) ? y
: scm_makdbl(z
, 0.0);
2388 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_max
);
2389 if SCM_INUMP(y
) return SCM_BIGSIGN(x
) ? y
: x
;
2390 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
2391 return (1==scm_bigcomp(x
, y
)) ? y
: x
;
2395 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
2396 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_max
);
2398 return SCM_BIGSIGN(y
) ? x
: y
;
2401 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_max
);
2402 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_max
);
2405 return ((long)x
< (long)y
) ? y
: x
;
2411 SCM_PROC1 (s_min
, "min", scm_tc7_asubr
, scm_min
);
2423 if (!(SCM_NUMBERP(x
)))
2424 badx
:scm_wta(x
, (char *)SCM_ARG1
, s_min
);
2431 SCM_ASRTGO(SCM_NIMP(x
), badx
);
2433 if SCM_INUMP(y
) return SCM_BIGSIGN(x
) ? x
: y
;
2434 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2435 if SCM_BIGP(y
) return (-1==scm_bigcomp(x
, y
)) ? y
: x
;
2436 SCM_ASRTGO(SCM_REALP(y
), bady
);
2438 return (z
> SCM_REALPART(y
)) ? y
: scm_makdbl(z
, 0.0);
2440 SCM_ASRTGO(SCM_REALP(x
), badx
);
2442 SCM_ASSERT(SCM_NIMP(x
) && SCM_REALP(x
), x
, SCM_ARG1
, s_min
);
2444 if SCM_INUMP(y
) return (SCM_REALPART(x
) > (z
= SCM_INUM(y
))) ? scm_makdbl(z
, 0.0) : x
;
2446 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2447 if SCM_BIGP(y
) return (SCM_REALPART(x
) > (z
= scm_big2dbl(y
))) ? scm_makdbl(z
, 0.0) : x
;
2448 SCM_ASRTGO(SCM_REALP(y
), bady
);
2450 SCM_ASRTGO(SCM_NIMP(y
) && SCM_REALP(y
), bady
);
2452 return (SCM_REALPART(x
) > SCM_REALPART(y
)) ? y
: x
;
2456 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2457 if SCM_BIGP(y
) return SCM_BIGSIGN(y
) ? y
: x
;
2459 if (!(SCM_REALP(y
)))
2460 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_min
);
2464 if (!(SCM_NIMP(y
) && SCM_REALP(y
)))
2465 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_min
);
2468 return ((z
= SCM_INUM(x
)) > SCM_REALPART(y
)) ? y
: scm_makdbl(z
, 0.0);
2473 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_min
);
2474 if SCM_INUMP(y
) return SCM_BIGSIGN(x
) ? x
: y
;
2475 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
2476 return (-1==scm_bigcomp(x
, y
)) ? y
: x
;
2480 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
2481 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_min
);
2483 return SCM_BIGSIGN(y
) ? y
: x
;
2486 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_min
);
2487 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_min
);
2490 return ((long)x
> (long)y
) ? y
: x
;
2496 SCM_PROC1 (s_sum
, "+", scm_tc7_asubr
, scm_sum
);
2504 if SCM_UNBNDP(x
) return SCM_INUM0
;
2506 if (!(SCM_NUMBERP(x
)))
2507 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_sum
);
2515 SCM_ASRTGO(SCM_NIMP(x
), badx
);
2517 if SCM_INUMP(y
) {t
= x
; x
= y
; y
= t
; goto intbig
;}
2518 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2520 if (SCM_NUMDIGS(x
) > SCM_NUMDIGS(y
)) {t
= x
; x
= y
; y
= t
;}
2521 return scm_addbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BIGSIGN(x
), y
, 0);
2523 SCM_ASRTGO(SCM_INEXP(y
), bady
);
2524 bigreal
: return scm_makdbl(scm_big2dbl(x
)+SCM_REALPART(y
), SCM_CPLXP(y
)?SCM_IMAG(y
):0.0);
2526 SCM_ASRTGO(SCM_INEXP(x
), badx
);
2528 SCM_ASRTGO(SCM_NIMP(x
) && SCM_INEXP(x
), badx
);
2530 if SCM_INUMP(y
) {t
= x
; x
= y
; y
= t
; goto intreal
;}
2532 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2533 if SCM_BIGP(y
) {t
= x
; x
= y
; y
= t
; goto bigreal
;}
2535 else if (!(SCM_INEXP(y
)))
2536 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_sum
);
2540 if (!(SCM_NIMP(y
) && SCM_INEXP(y
)))
2541 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_sum
);
2545 if SCM_CPLXP(x
) i
= SCM_IMAG(x
);
2546 if SCM_CPLXP(y
) i
+= SCM_IMAG(y
);
2547 return scm_makdbl(SCM_REALPART(x
)+SCM_REALPART(y
), i
); }
2551 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2554 # ifndef SCM_DIGSTOOBIG
2555 long z
= scm_pseudolong(SCM_INUM(x
));
2556 return scm_addbig((SCM_BIGDIG
*)&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
2558 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
2559 scm_longdigs(SCM_INUM(x
), zdigs
);
2560 return scm_addbig(zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
2563 SCM_ASRTGO(SCM_INEXP(y
), bady
);
2565 SCM_ASRTGO(SCM_NIMP(y
) && SCM_INEXP(y
), bady
);
2567 intreal
: return scm_makdbl(SCM_INUM(x
)+SCM_REALPART(y
), SCM_CPLXP(y
)?SCM_IMAG(y
):0.0);
2573 SCM_ASRTGO(SCM_NIMP(x
) && SCM_BIGP(x
), badx
);
2574 if SCM_INUMP(y
) {t
= x
; x
= y
; y
= t
; goto intbig
;}
2575 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
2576 if (SCM_NUMDIGS(x
) > SCM_NUMDIGS(y
)) {t
= x
; x
= y
; y
= t
;}
2577 return scm_addbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BIGSIGN(x
), y
, 0);
2581 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
2582 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_sum
);
2585 # ifndef SCM_DIGSTOOBIG
2586 long z
= scm_pseudolong(SCM_INUM(x
));
2587 return scm_addbig(&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
2589 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
2590 scm_longdigs(SCM_INUM(x
), zdigs
);
2591 return scm_addbig(zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
2596 SCM_ASRTGO(SCM_INUMP(x
), badx
);
2597 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_sum
);
2600 x
= SCM_INUM(x
)+SCM_INUM(y
);
2601 if SCM_FIXABLE(x
) return SCM_MAKINUM(x
);
2603 return scm_long2big(x
);
2606 return scm_makdbl((double)x
, 0.0);
2608 scm_num_overflow (s_sum
);
2609 return SCM_UNSPECIFIED
;
2617 SCM_PROC1 (s_difference
, "-", scm_tc7_asubr
, scm_difference
);
2620 scm_difference(x
, y
)
2628 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_difference
);
2633 x
= scm_copybig(x
, !SCM_BIGSIGN(x
));
2634 return SCM_NUMDIGS(x
) * SCM_BITSPERDIG
/SCM_CHAR_BIT
<= sizeof(SCM
) ?
2635 scm_big2inum(x
, SCM_NUMDIGS(x
)) : x
;
2638 SCM_ASRTGO(SCM_INEXP(x
), badx
);
2639 return scm_makdbl(-SCM_REALPART(x
), SCM_CPLXP(x
)?-SCM_IMAG(x
):0.0);
2641 if SCM_INUMP(y
) return scm_sum(x
, SCM_MAKINUM(-SCM_INUM(y
)));
2643 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2645 if SCM_BIGP(y
) return (SCM_NUMDIGS(x
) < SCM_NUMDIGS(y
)) ?
2646 scm_addbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BIGSIGN(x
), y
, 0x0100) :
2647 scm_addbig(SCM_BDIGITS(y
), SCM_NUMDIGS(y
), SCM_BIGSIGN(y
) ^ 0x0100, x
, 0);
2648 SCM_ASRTGO(SCM_INEXP(y
), bady
);
2649 return scm_makdbl(scm_big2dbl(x
)-SCM_REALPART(y
), SCM_CPLXP(y
)?-SCM_IMAG(y
):0.0);
2651 SCM_ASRTGO(SCM_INEXP(x
), badx
);
2652 if SCM_BIGP(y
) return scm_makdbl(SCM_REALPART(x
)-scm_big2dbl(y
), SCM_CPLXP(x
)?SCM_IMAG(x
):0.0);
2653 SCM_ASRTGO(SCM_INEXP(y
), bady
);
2655 SCM_ASRTGO(SCM_INEXP(x
), badx
);
2656 SCM_ASRTGO(SCM_NIMP(y
) && SCM_INEXP(y
), bady
);
2661 return scm_makdbl (SCM_REAL (x
) - SCM_REAL (y
),
2662 SCM_IMAG (x
) - SCM_IMAG (y
));
2664 return scm_makdbl (SCM_REAL (x
) - SCM_REALPART(y
), SCM_IMAG (x
));
2666 return scm_makdbl (SCM_REALPART (x
) - SCM_REALPART (y
),
2667 SCM_CPLXP(y
) ? - SCM_IMAG (y
) : 0.0);
2669 if SCM_UNBNDP(y
) {x
= -SCM_INUM(x
); goto checkx
;}
2672 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2674 # ifndef SCM_DIGSTOOBIG
2675 long z
= scm_pseudolong(SCM_INUM(x
));
2676 return scm_addbig((SCM_BIGDIG
*)&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0x0100);
2678 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
2679 scm_longdigs(SCM_INUM(x
), zdigs
);
2680 return scm_addbig(zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0x0100);
2684 if (!(SCM_INEXP(y
)))
2685 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_difference
);
2689 if (!(SCM_NIMP(y
) && SCM_INEXP(y
)))
2690 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_difference
);
2693 return scm_makdbl(SCM_INUM(x
)-SCM_REALPART(y
), SCM_CPLXP(y
)?-SCM_IMAG(y
):0.0);
2698 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_difference
);
2700 x
= scm_copybig(x
, !SCM_BIGSIGN(x
));
2701 return SCM_NUMDIGS(x
) * SCM_BITSPERDIG
/SCM_CHAR_BIT
<= sizeof(SCM
) ?
2702 scm_big2inum(x
, SCM_NUMDIGS(x
)) : x
;
2705 # ifndef SCM_DIGSTOOBIG
2706 long z
= scm_pseudolong(SCM_INUM(y
));
2707 return scm_addbig(&z
, SCM_DIGSPERLONG
, (y
< 0) ? 0 : 0x0100, x
, 0);
2709 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
2710 scm_longdigs(SCM_INUM(x
), zdigs
);
2711 return scm_addbig(zdigs
, SCM_DIGSPERLONG
, (y
< 0) ? 0 : 0x0100, x
, 0);
2714 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
2715 return (SCM_NUMDIGS(x
) < SCM_NUMDIGS(y
)) ?
2716 scm_addbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BIGSIGN(x
), y
, 0x0100) :
2717 scm_addbig(SCM_BDIGITS(y
), SCM_NUMDIGS(y
), SCM_BIGSIGN(y
) ^ 0x0100, x
, 0);
2719 if SCM_UNBNDP(y
) {x
= -SCM_INUM(x
); goto checkx
;}
2722 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
2723 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_difference
);
2726 # ifndef SCM_DIGSTOOBIG
2727 long z
= scm_pseudolong(SCM_INUM(x
));
2728 return scm_addbig(&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0x0100);
2730 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
2731 scm_longdigs(SCM_INUM(x
), zdigs
);
2732 return scm_addbig(zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0x0100);
2737 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_difference
);
2738 if SCM_UNBNDP(y
) {x
= -SCM_INUM(x
); goto checkx
;}
2739 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_difference
);
2742 x
= SCM_INUM(x
)-SCM_INUM(y
);
2744 if SCM_FIXABLE(x
) return SCM_MAKINUM(x
);
2746 return scm_long2big(x
);
2749 return scm_makdbl((double)x
, 0.0);
2751 scm_num_overflow (s_difference
);
2752 return SCM_UNSPECIFIED
;
2760 SCM_PROC1 (s_product
, "*", scm_tc7_asubr
, scm_product
);
2768 if SCM_UNBNDP(x
) return SCM_MAKINUM(1L);
2770 if (!(SCM_NUMBERP(x
)))
2771 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_product
);
2779 SCM_ASRTGO(SCM_NIMP(x
), badx
);
2781 if SCM_INUMP(y
) {t
= x
; x
= y
; y
= t
; goto intbig
;}
2782 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2783 if SCM_BIGP(y
) return scm_mulbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
2784 SCM_BIGSIGN(x
) ^ SCM_BIGSIGN(y
));
2785 SCM_ASRTGO(SCM_INEXP(y
), bady
);
2787 double bg
= scm_big2dbl(x
);
2788 return scm_makdbl(bg
*SCM_REALPART(y
), SCM_CPLXP(y
)?bg
*SCM_IMAG(y
):0.0); }
2790 SCM_ASRTGO(SCM_INEXP(x
), badx
);
2792 SCM_ASRTGO(SCM_NIMP(x
) && SCM_INEXP(x
), badx
);
2794 if SCM_INUMP(y
) {t
= x
; x
= y
; y
= t
; goto intreal
;}
2796 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2797 if SCM_BIGP(y
) {t
= x
; x
= y
; y
= t
; goto bigreal
;}
2799 else if (!(SCM_INEXP(y
)))
2800 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_product
);
2804 if (!(SCM_NIMP(y
) && SCM_INEXP(y
)))
2805 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_product
);
2811 return scm_makdbl (SCM_REAL (x
) * SCM_REAL (y
)
2812 - SCM_IMAG (x
) * SCM_IMAG (y
),
2813 SCM_REAL (x
) * SCM_IMAG (y
)
2814 + SCM_IMAG (x
) * SCM_REAL (y
));
2816 return scm_makdbl (SCM_REAL (x
) * SCM_REALPART (y
),
2817 SCM_IMAG (x
) * SCM_REALPART(y
));
2819 return scm_makdbl (SCM_REALPART (x
) * SCM_REALPART (y
),
2820 SCM_CPLXP (y
) ? SCM_REALPART (x
) * SCM_IMAG (y
) : 0.0);
2824 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2826 intbig
: if (SCM_INUM0
==x
) return x
; if (SCM_MAKINUM(1L)==x
) return y
;
2828 # ifndef SCM_DIGSTOOBIG
2829 long z
= scm_pseudolong(SCM_INUM(x
));
2830 return scm_mulbig((SCM_BIGDIG
*)&z
, SCM_DIGSPERLONG
, SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
2831 SCM_BIGSIGN(y
) ? (x
>0) : (x
<0));
2833 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
2834 scm_longdigs(SCM_INUM(x
), zdigs
);
2835 return scm_mulbig(zdigs
, SCM_DIGSPERLONG
, SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
2836 SCM_BIGSIGN(y
) ? (x
>0) : (x
<0));
2840 SCM_ASRTGO(SCM_INEXP(y
), bady
);
2842 SCM_ASRTGO(SCM_NIMP(y
) && SCM_INEXP(y
), bady
);
2844 intreal
: return scm_makdbl(SCM_INUM(x
)*SCM_REALPART(y
), SCM_CPLXP(y
)?SCM_INUM(x
)*SCM_IMAG(y
):0.0);
2849 SCM_ASRTGO(SCM_NIMP(x
) && SCM_BIGP(x
), badx
);
2850 if SCM_INUMP(y
) {SCM t
= x
; x
= y
; y
= t
; goto intbig
;}
2851 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
2852 return scm_mulbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
2853 SCM_BIGSIGN(x
) ^ SCM_BIGSIGN(y
));
2857 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
2858 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_product
);
2860 intbig
: if (SCM_INUM0
==x
) return x
; if (SCM_MAKINUM(1L)==x
) return y
;
2862 # ifndef SCM_DIGSTOOBIG
2863 long z
= scm_pseudolong(SCM_INUM(x
));
2864 return scm_mulbig(&z
, SCM_DIGSPERLONG
, SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
2865 SCM_BIGSIGN(y
) ? (x
>0) : (x
<0));
2867 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
2868 scm_longdigs(SCM_INUM(x
), zdigs
);
2869 return scm_mulbig(zdigs
, SCM_DIGSPERLONG
, SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
2870 SCM_BIGSIGN(y
) ? (x
>0) : (x
<0));
2875 SCM_ASRTGO(SCM_INUMP(x
), badx
);
2876 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_product
);
2886 if (k
!= SCM_INUM(y
) || k
/i
!= j
)
2888 { int sgn
= (i
< 0) ^ (j
< 0);
2889 # ifndef SCM_DIGSTOOBIG
2890 i
= scm_pseudolong(i
);
2891 j
= scm_pseudolong(j
);
2892 return scm_mulbig((SCM_BIGDIG
*)&i
, SCM_DIGSPERLONG
,
2893 (SCM_BIGDIG
*)&j
, SCM_DIGSPERLONG
, sgn
);
2894 # else /* SCM_DIGSTOOBIG */
2895 SCM_BIGDIG idigs
[SCM_DIGSPERLONG
];
2896 SCM_BIGDIG jdigs
[SCM_DIGSPERLONG
];
2897 scm_longdigs(i
, idigs
);
2898 scm_longdigs(j
, jdigs
);
2899 return scm_mulbig(idigs
, SCM_DIGSPERLONG
, jdigs
, SCM_DIGSPERLONG
, sgn
);
2904 return scm_makdbl(((double)i
)*((double)j
), 0.0);
2906 scm_num_overflow (s_product
);
2916 scm_num2dbl (a
, why
)
2921 return (double) SCM_INUM (a
);
2923 SCM_ASSERT (SCM_NIMP (a
), a
, "wrong type argument", why
);
2925 return (SCM_REALPART (a
));
2928 return scm_big2dbl (a
);
2930 SCM_ASSERT (0, a
, "wrong type argument", why
);
2931 return SCM_UNSPECIFIED
;
2935 SCM_PROC1 (s_divide
, "/", scm_tc7_asubr
, scm_divide
);
2947 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_divide
);
2951 if SCM_BIGP(x
) return scm_makdbl(1.0/scm_big2dbl(x
), 0.0);
2953 SCM_ASRTGO(SCM_INEXP(x
), badx
);
2954 if SCM_REALP(x
) return scm_makdbl(1.0/SCM_REALPART(x
), 0.0);
2955 r
= SCM_REAL(x
); i
= SCM_IMAG(x
); d
= r
*r
+i
*i
;
2956 return scm_makdbl(r
/d
, -i
/d
);
2965 scm_num_overflow (s_divide
);
2969 if (z
< SCM_BIGRAD
) {
2970 SCM w
= scm_copybig(x
, SCM_BIGSIGN(x
) ? (y
>0) : (y
<0));
2971 return scm_divbigdig(SCM_BDIGITS(w
), SCM_NUMDIGS(w
), (SCM_BIGDIG
)z
) ?
2972 scm_makdbl(scm_big2dbl(x
)/SCM_INUM(y
), 0.0) : scm_normbig(w
);
2974 # ifndef SCM_DIGSTOOBIG
2975 z
= scm_pseudolong(z
);
2976 z
= scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), (SCM_BIGDIG
*)&z
, SCM_DIGSPERLONG
,
2977 SCM_BIGSIGN(x
) ? (y
>0) : (y
<0), 3);
2979 { SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
2980 scm_longdigs(z
, zdigs
);
2981 z
= scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), zdigs
, SCM_DIGSPERLONG
,
2982 SCM_BIGSIGN(x
) ? (y
>0) : (y
<0), 3);}
2984 return z
? z
: scm_makdbl(scm_big2dbl(x
)/SCM_INUM(y
), 0.0);
2986 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2988 z
= scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
2989 SCM_BIGSIGN(x
) ^ SCM_BIGSIGN(y
), 3);
2990 return z
? z
: scm_makdbl(scm_big2dbl(x
)/scm_big2dbl(y
), 0.0);
2992 SCM_ASRTGO(SCM_INEXP(y
), bady
);
2993 if SCM_REALP(y
) return scm_makdbl(scm_big2dbl(x
)/SCM_REALPART(y
), 0.0);
2998 SCM_ASRTGO(SCM_INEXP(x
), badx
);
2999 if SCM_INUMP(y
) {d
= SCM_INUM(y
); goto basic_div
;}
3001 SCM_ASRTGO(SCM_NIMP(y
), bady
);
3002 if SCM_BIGP(y
) {d
= scm_big2dbl(y
); goto basic_div
;}
3003 SCM_ASRTGO(SCM_INEXP(y
), bady
);
3005 SCM_ASRTGO(SCM_NIMP(y
) && SCM_INEXP(y
), bady
);
3008 d
= SCM_REALPART(y
);
3009 basic_div
: return scm_makdbl(SCM_REALPART(x
)/d
, SCM_CPLXP(x
)?SCM_IMAG(x
)/d
:0.0);
3011 a
= SCM_REALPART(x
);
3012 if SCM_REALP(x
) goto complex_div
;
3013 r
= SCM_REAL(y
); i
= SCM_IMAG(y
); d
= r
*r
+i
*i
;
3014 return scm_makdbl((a
*r
+SCM_IMAG(x
)*i
)/d
, (SCM_IMAG(x
)*r
-a
*i
)/d
);
3017 if ((SCM_MAKINUM(1L)==x
) || (SCM_MAKINUM(-1L)==x
)) return x
;
3018 return scm_makdbl(1.0/((double)SCM_INUM(x
)), 0.0);
3022 SCM_ASRTGO(SCM_NIMP(y
), bady
);
3023 if SCM_BIGP(y
) return scm_makdbl(SCM_INUM(x
)/scm_big2dbl(y
), 0.0);
3025 if (!(SCM_INEXP(y
)))
3026 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_divide
);
3030 if (!(SCM_NIMP(y
) && SCM_INEXP(y
)))
3031 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_divide
);
3035 return scm_makdbl(SCM_INUM(x
)/SCM_REALPART(y
), 0.0);
3038 r
= SCM_REAL(y
); i
= SCM_IMAG(y
); d
= r
*r
+i
*i
;
3039 return scm_makdbl((a
*r
)/d
, (-a
*i
)/d
);
3045 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_divide
);
3046 if SCM_UNBNDP(y
) goto ov
;
3052 if (z
< SCM_BIGRAD
) {
3053 SCM w
= scm_copybig(x
, SCM_BIGSIGN(x
) ? (y
>0) : (y
<0));
3054 if (scm_divbigdig(SCM_BDIGITS(w
), SCM_NUMDIGS(w
), (SCM_BIGDIG
)z
)) goto ov
;
3057 # ifndef SCM_DIGSTOOBIG
3058 z
= scm_pseudolong(z
);
3059 z
= scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), &z
, SCM_DIGSPERLONG
,
3060 SCM_BIGSIGN(x
) ? (y
>0) : (y
<0), 3);
3062 { SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3063 scm_longdigs(z
, zdigs
);
3064 z
= scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), zdigs
, SCM_DIGSPERLONG
,
3065 SCM_BIGSIGN(x
) ? (y
>0) : (y
<0), 3);}
3068 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
3069 z
= scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
3070 SCM_BIGSIGN(x
) ^ SCM_BIGSIGN(y
), 3);
3076 if ((SCM_MAKINUM(1L)==x
) || (SCM_MAKINUM(-1L)==x
)) return x
;
3081 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
3082 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_divide
);
3087 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_divide
);
3089 if ((SCM_MAKINUM(1L)==x
) || (SCM_MAKINUM(-1L)==x
)) return x
;
3092 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_divide
);
3096 long z
= SCM_INUM(y
);
3097 if ((0==z
) || SCM_INUM(x
)%z
) goto ov
;
3099 if SCM_FIXABLE(z
) return SCM_MAKINUM(z
);
3101 return scm_long2big(z
);
3104 ov
: return scm_makdbl(((double)SCM_INUM(x
))/((double)SCM_INUM(y
)), 0.0);
3106 ov
: scm_num_overflow (s_divide
);
3107 return SCM_UNSPECIFIED
;
3116 SCM_PROC1 (s_asinh
, "$asinh", scm_tc7_cxr
, (SCM (*)()) scm_asinh
);
3122 return log(x
+sqrt(x
*x
+1));
3128 SCM_PROC1 (s_acosh
, "$acosh", scm_tc7_cxr
, (SCM (*)()) scm_acosh
);
3134 return log(x
+sqrt(x
*x
-1));
3140 SCM_PROC1 (s_atanh
, "$atanh", scm_tc7_cxr
, (SCM (*)()) scm_atanh
);
3146 return 0.5*log((1+x
)/(1-x
));
3152 SCM_PROC1 (s_truncate
, "truncate", scm_tc7_cxr
, (SCM (*)()) scm_truncate
);
3158 if (x
< 0.0) return -floor(-x
);
3164 SCM_PROC1 (s_round
, "round", scm_tc7_cxr
, (SCM (*)()) scm_round
);
3170 double plus_half
= x
+ 0.5;
3171 double result
= floor(plus_half
);
3172 /* Adjust so that the scm_round is towards even. */
3173 return (plus_half
== result
&& plus_half
/ 2 != floor(plus_half
/ 2))
3174 ? result
- 1 : result
;
3179 SCM_PROC1 (s_exact_to_inexact
, "exact->inexact", scm_tc7_cxr
, (SCM (*)()) scm_exact_to_inexact
);
3182 scm_exact_to_inexact(z
)
3189 SCM_PROC1 (s_i_floor
, "floor", scm_tc7_cxr
, (SCM (*)()) floor
);
3190 SCM_PROC1 (s_i_ceil
, "ceiling", scm_tc7_cxr
, (SCM (*)()) ceil
);
3191 SCM_PROC1 (s_i_sqrt
, "$sqrt", scm_tc7_cxr
, (SCM (*)())sqrt
);
3192 SCM_PROC1 (s_i_abs
, "$abs", scm_tc7_cxr
, (SCM (*)())fabs
);
3193 SCM_PROC1 (s_i_exp
, "$exp", scm_tc7_cxr
, (SCM (*)())exp
);
3194 SCM_PROC1 (s_i_log
, "$log", scm_tc7_cxr
, (SCM (*)())log
);
3195 SCM_PROC1 (s_i_sin
, "$sin", scm_tc7_cxr
, (SCM (*)())sin
);
3196 SCM_PROC1 (s_i_cos
, "$cos", scm_tc7_cxr
, (SCM (*)())cos
);
3197 SCM_PROC1 (s_i_tan
, "$tan", scm_tc7_cxr
, (SCM (*)())tan
);
3198 SCM_PROC1 (s_i_asin
, "$asin", scm_tc7_cxr
, (SCM (*)())asin
);
3199 SCM_PROC1 (s_i_acos
, "$acos", scm_tc7_cxr
, (SCM (*)())acos
);
3200 SCM_PROC1 (s_i_atan
, "$atan", scm_tc7_cxr
, (SCM (*)())atan
);
3201 SCM_PROC1 (s_i_sinh
, "$sinh", scm_tc7_cxr
, (SCM (*)())sinh
);
3202 SCM_PROC1 (s_i_cosh
, "$cosh", scm_tc7_cxr
, (SCM (*)())cosh
);
3203 SCM_PROC1 (s_i_tanh
, "$tanh", scm_tc7_cxr
, (SCM (*)())tanh
);
3205 struct dpair
{double x
, y
;};
3207 static void scm_two_doubles
SCM_P ((SCM z1
, SCM z2
, char *sstring
, struct dpair
*xy
));
3210 scm_two_doubles(z1
, z2
, sstring
, xy
)
3215 if SCM_INUMP(z1
) xy
->x
= SCM_INUM(z1
);
3218 SCM_ASRTGO(SCM_NIMP(z1
), badz1
);
3219 if SCM_BIGP(z1
) xy
->x
= scm_big2dbl(z1
);
3222 if (!(SCM_REALP(z1
)))
3223 badz1
: scm_wta(z1
, (char *)SCM_ARG1
, sstring
);
3225 xy
->x
= SCM_REALPART(z1
);}
3227 {SCM_ASSERT(SCM_NIMP(z1
) && SCM_REALP(z1
), z1
, SCM_ARG1
, sstring
);
3228 xy
->x
= SCM_REALPART(z1
);}
3231 if SCM_INUMP(z2
) xy
->y
= SCM_INUM(z2
);
3234 SCM_ASRTGO(SCM_NIMP(z2
), badz2
);
3235 if SCM_BIGP(z2
) xy
->y
= scm_big2dbl(z2
);
3238 if (!(SCM_REALP(z2
)))
3239 badz2
: scm_wta(z2
, (char *)SCM_ARG2
, sstring
);
3241 xy
->y
= SCM_REALPART(z2
);}
3243 {SCM_ASSERT(SCM_NIMP(z2
) && SCM_REALP(z2
), z2
, SCM_ARG2
, sstring
);
3244 xy
->y
= SCM_REALPART(z2
);}
3252 SCM_PROC(s_sys_expt
, "$expt", 2, 0, 0, scm_sys_expt
);
3255 scm_sys_expt(z1
, z2
)
3260 scm_two_doubles(z1
, z2
, s_sys_expt
, &xy
);
3261 return scm_makdbl(pow(xy
.x
, xy
.y
), 0.0);
3266 SCM_PROC(s_sys_atan2
, "$atan2", 2, 0, 0, scm_sys_atan2
);
3269 scm_sys_atan2(z1
, z2
)
3274 scm_two_doubles(z1
, z2
, s_sys_atan2
, &xy
);
3275 return scm_makdbl(atan2(xy
.x
, xy
.y
), 0.0);
3280 SCM_PROC(s_make_rectangular
, "make-rectangular", 2, 0, 0, scm_make_rectangular
);
3283 scm_make_rectangular(z1
, z2
)
3288 scm_two_doubles(z1
, z2
, s_make_rectangular
, &xy
);
3289 return scm_makdbl(xy
.x
, xy
.y
);
3294 SCM_PROC(s_make_polar
, "make-polar", 2, 0, 0, scm_make_polar
);
3297 scm_make_polar(z1
, z2
)
3302 scm_two_doubles(z1
, z2
, s_make_polar
, &xy
);
3303 return scm_makdbl(xy
.x
*cos(xy
.y
), xy
.x
*sin(xy
.y
));
3309 SCM_PROC(s_real_part
, "real-part", 1, 0, 0, scm_real_part
);
3317 SCM_ASRTGO(SCM_NIMP(z
), badz
);
3318 if SCM_BIGP(z
) return z
;
3320 if (!(SCM_INEXP(z
)))
3321 badz
: scm_wta(z
, (char *)SCM_ARG1
, s_real_part
);
3324 SCM_ASSERT(SCM_NIMP(z
) && SCM_INEXP(z
), z
, SCM_ARG1
, s_real_part
);
3326 if SCM_CPLXP(z
) return scm_makdbl(SCM_REAL(z
), 0.0);
3333 SCM_PROC(s_imag_part
, "imag-part", 1, 0, 0, scm_imag_part
);
3339 if SCM_INUMP(z
) return SCM_INUM0
;
3341 SCM_ASRTGO(SCM_NIMP(z
), badz
);
3342 if SCM_BIGP(z
) return SCM_INUM0
;
3344 if (!(SCM_INEXP(z
)))
3345 badz
: scm_wta(z
, (char *)SCM_ARG1
, s_imag_part
);
3348 SCM_ASSERT(SCM_NIMP(z
) && SCM_INEXP(z
), z
, SCM_ARG1
, s_imag_part
);
3350 if SCM_CPLXP(z
) return scm_makdbl(SCM_IMAG(z
), 0.0);
3356 SCM_PROC(s_magnitude
, "magnitude", 1, 0, 0, scm_magnitude
);
3362 if SCM_INUMP(z
) return scm_abs(z
);
3364 SCM_ASRTGO(SCM_NIMP(z
), badz
);
3365 if SCM_BIGP(z
) return scm_abs(z
);
3367 if (!(SCM_INEXP(z
)))
3368 badz
: scm_wta(z
, (char *)SCM_ARG1
, s_magnitude
);
3371 SCM_ASSERT(SCM_NIMP(z
) && SCM_INEXP(z
), z
, SCM_ARG1
, s_magnitude
);
3375 double i
= SCM_IMAG(z
), r
= SCM_REAL(z
);
3376 return scm_makdbl(sqrt(i
*i
+r
*r
), 0.0);
3378 return scm_makdbl(fabs(SCM_REALPART(z
)), 0.0);
3384 SCM_PROC(s_angle
, "angle", 1, 0, 0, scm_angle
);
3391 if SCM_INUMP(z
) {x
= (z
>=SCM_INUM0
) ? 1.0 : -1.0; goto do_angle
;}
3393 SCM_ASRTGO(SCM_NIMP(z
), badz
);
3394 if SCM_BIGP(z
) {x
= (SCM_TYP16(z
)==scm_tc16_bigpos
) ? 1.0 : -1.0; goto do_angle
;}
3396 if (!(SCM_INEXP(z
))) {
3397 badz
: scm_wta(z
, (char *)SCM_ARG1
, s_angle
);}
3400 SCM_ASSERT(SCM_NIMP(z
) && SCM_INEXP(z
), z
, SCM_ARG1
, s_angle
);
3404 x
= SCM_REALPART(z
);
3407 x
= SCM_REAL(z
); y
= SCM_IMAG(z
);
3409 return scm_makdbl(atan2(y
, x
), 0.0);
3413 SCM_PROC(s_inexact_to_exact
, "inexact->exact", 1, 0, 0, scm_inexact_to_exact
);
3416 scm_inexact_to_exact(z
)
3419 if SCM_INUMP(z
) return z
;
3421 SCM_ASRTGO(SCM_NIMP(z
), badz
);
3422 if SCM_BIGP(z
) return z
;
3424 if (!(SCM_REALP(z
)))
3425 badz
: scm_wta(z
, (char *)SCM_ARG1
, s_inexact_to_exact
);
3428 SCM_ASSERT(SCM_NIMP(z
) && SCM_REALP(z
), z
, SCM_ARG1
, s_inexact_to_exact
);
3432 double u
= floor(SCM_REALPART(z
)+0.5);
3433 if ((u
<= SCM_MOST_POSITIVE_FIXNUM
) && (-u
<= -SCM_MOST_NEGATIVE_FIXNUM
)) {
3434 /* Negation is a workaround for HP700 cc bug */
3435 SCM ans
= SCM_MAKINUM((long)u
);
3436 if (SCM_INUM(ans
)==(long)u
) return ans
;
3438 SCM_ASRTGO(!IS_INF(u
), badz
); /* problem? */
3439 return scm_dbl2big(u
);
3442 return SCM_MAKINUM((long)floor(SCM_REALPART(z
)+0.5));
3448 #else /* ~SCM_FLOATS */
3449 SCM_PROC(s_trunc
, "truncate", 1, 0, 0, scm_trunc
);
3455 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_truncate
);
3461 #endif /* SCM_FLOATS */
3465 /* d must be integer */
3475 double u
= (d
< 0)?-d
:d
;
3476 while (0 != floor(u
)) {u
/= SCM_BIGRAD
;i
++;}
3477 ans
= scm_mkbig(i
, d
< 0);
3478 digits
= SCM_BDIGITS(ans
);
3487 scm_num_overflow ("dbl2big");
3500 scm_sizet i
= SCM_NUMDIGS(b
);
3501 SCM_BIGDIG
*digits
= SCM_BDIGITS(b
);
3502 while (i
--) ans
= digits
[i
] + SCM_BIGRAD
*ans
;
3503 if (scm_tc16_bigneg
==SCM_TYP16(b
)) return -ans
;
3514 if (!SCM_FIXABLE(sl
)) {
3516 return scm_long2big(sl
);
3519 return scm_makdbl((double) sl
, 0.0);
3525 return SCM_MAKINUM(sl
);
3532 scm_long_long2num(sl
)
3535 if (!SCM_FIXABLE(sl
)) {
3537 return scm_long_long2big(sl
);
3540 return scm_makdbl((double) sl
, 0.0);
3546 return SCM_MAKINUM(sl
);
3556 if (!SCM_POSFIXABLE(sl
)) {
3558 return scm_ulong2big(sl
);
3561 return scm_makdbl((double) sl
, 0.0);
3567 return SCM_MAKINUM(sl
);
3572 scm_num2long(num
, pos
, s_caller
)
3580 res
= SCM_INUM(num
);
3583 SCM_ASRTGO(SCM_NIMP(num
), errout
);
3587 double u
= SCM_REALPART(num
);
3589 if ((double)res
== u
)
3596 if (SCM_BIGP(num
)) {
3601 for(l
= SCM_NUMDIGS(num
);l
--;)
3603 res
= SCM_BIGUP(res
) + SCM_BDIGITS(num
)[l
];
3608 if (SCM_TYP16 (num
) == scm_tc16_bigpos
)
3614 errout
: scm_wta(num
, pos
, s_caller
);
3615 return SCM_UNSPECIFIED
;
3623 num2long(num
, pos
, s_caller
)
3630 res
= SCM_INUM((long)num
);
3633 SCM_ASRTGO(SCM_NIMP(num
), errout
);
3636 double u
= SCM_REALPART(num
);
3637 if (((SCM_MOST_NEGATIVE_FIXNUM
* 4) <= u
)
3638 && (u
<= (SCM_MOST_POSITIVE_FIXNUM
* 4 + 3))) {
3646 scm_sizet l
= SCM_NUMDIGS(num
);
3647 SCM_ASRTGO(SCM_DIGSPERLONG
>= l
, errout
);
3649 for(;l
--;) res
= SCM_BIGUP(res
) + SCM_BDIGITS(num
)[l
];
3653 errout
: scm_wta(num
, pos
, s_caller
);
3654 return SCM_UNSPECIFIED
;
3661 scm_num2long_long(num
, pos
, s_caller
)
3668 res
= SCM_INUM((long_long
)num
);
3671 SCM_ASRTGO(SCM_NIMP(num
), errout
);
3674 double u
= SCM_REALPART(num
);
3675 if (((SCM_MOST_NEGATIVE_FIXNUM
* 4) <= u
)
3676 && (u
<= (SCM_MOST_POSITIVE_FIXNUM
* 4 + 3))) {
3684 scm_sizet l
= SCM_NUMDIGS(num
);
3685 SCM_ASRTGO(SCM_DIGSPERLONGLONG
>= l
, errout
);
3687 for(;l
--;) res
= SCM_LONGLONGBIGUP(res
) + SCM_BDIGITS(num
)[l
];
3691 errout
: scm_wta(num
, pos
, s_caller
);
3692 return SCM_UNSPECIFIED
;
3699 scm_num2ulong(num
, pos
, s_caller
)
3707 res
= SCM_INUM((unsigned long)num
);
3710 SCM_ASRTGO(SCM_NIMP(num
), errout
);
3714 double u
= SCM_REALPART(num
);
3715 if ((0 <= u
) && (u
<= (unsigned long)~0L))
3723 if (SCM_BIGP(num
)) {
3724 unsigned long oldres
;
3728 for(l
= SCM_NUMDIGS(num
);l
--;)
3730 res
= SCM_BIGUP(res
) + SCM_BDIGITS(num
)[l
];
3738 errout
: scm_wta(num
, pos
, s_caller
);
3739 return SCM_UNSPECIFIED
;
3745 static void add1
SCM_P ((double f
, double *fsum
));
3746 static void add1(f
, fsum
)
3760 SCM_NEWCELL(scm_flo0
);
3762 SCM_SETCAR (scm_flo0
, scm_tc_flo
);
3763 SCM_FLO(scm_flo0
) = 0.0;
3765 SCM_SETCDR (scm_flo0
, (SCM
)scm_must_malloc(1L*sizeof(double), "real"));
3766 SCM_REAL(scm_flo0
) = 0.0;
3767 SCM_SETCAR (scm_flo0
, scm_tc_dblr
);
3770 scm_dblprec
= (DBL_DIG
> 20) ? 20 : DBL_DIG
;
3772 { /* determine floating point precision */
3774 double fsum
= 1.0+f
;
3775 while (fsum
!= 1.0) {
3777 if (++scm_dblprec
> 20) break;
3780 scm_dblprec
= scm_dblprec
-1;
3782 # endif /* DBL_DIG */
3784 #include "numbers.x"