1 /* Copyright (C) 1995,1996 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, 675 Mass Ave, Cambridge, MA 02139, USA.
17 * As a special exception, the Free Software Foundation gives permission
18 * for additional uses of the text contained in its release of GUILE.
20 * The exception is that, if you link the GUILE library with other files
21 * to produce an executable, this does not by itself cause the
22 * resulting executable to be covered by the GNU General Public License.
23 * Your use of that executable is in no way restricted on account of
24 * linking the GUILE library code into it.
26 * This exception does not however invalidate any other reasons why
27 * the executable file might be covered by the GNU General Public License.
29 * This exception applies only to the code released by the
30 * Free Software Foundation under the name GUILE. If you copy
31 * code from other Free Software Foundation releases into a copy of
32 * GUILE, as the General Public License permits, the exception does
33 * not apply to the code that you add in this way. To avoid misleading
34 * anyone as to the status of such modified files, you must delete
35 * this exception notice from them.
37 * If you write modifications of your own for GUILE, it is your choice
38 * whether to permit this exception to apply to your modifications.
39 * 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
);
95 if SCM_INUMP(x
) return SCM_BOOL_T
;
97 if (SCM_NIMP(x
) && SCM_BIGP(x
)) return SCM_BOOL_T
;
102 SCM_PROC(s_odd_p
, "odd?", 1, 0, 0, scm_odd_p
);
114 SCM_ASSERT(SCM_NIMP(n
) && SCM_BIGP(n
), n
, SCM_ARG1
, s_odd_p
);
115 return (1 & SCM_BDIGITS(n
)[0]) ? SCM_BOOL_T
: SCM_BOOL_F
;
118 SCM_ASSERT(SCM_INUMP(n
), n
, SCM_ARG1
, s_odd_p
);
120 return (4 & (int)n
) ? SCM_BOOL_T
: SCM_BOOL_F
;
123 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_PROC(s_abs
, "abs", 1, 0, 0, scm_abs
);
156 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_abs
);
157 if (SCM_TYP16(x
)==scm_tc16_bigpos
) return x
;
158 return scm_copybig(x
, 0);
161 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_abs
);
163 if (SCM_INUM(x
) >= 0) return x
;
165 if (!SCM_POSFIXABLE(x
))
167 return scm_long2big(x
);
169 scm_num_overflow (s_abs
);
171 return SCM_MAKINUM(x
);
174 SCM_PROC(s_quotient
, "quotient", 2, 0, 0, scm_quotient
);
177 scm_quotient(SCM x
, SCM y
)
189 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_quotient
);
191 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
192 return scm_divbigbig(SCM_BDIGITS(x
),
196 SCM_BIGSIGN(x
) ^ SCM_BIGSIGN(y
),
203 if (z
< SCM_BIGRAD
) {
204 w
= scm_copybig(x
, SCM_BIGSIGN(x
) ? (y
>0) : (y
<0));
205 scm_divbigdig(SCM_BDIGITS(w
), SCM_NUMDIGS(w
), (SCM_BIGDIG
)z
);
206 return scm_normbig(w
);
208 #ifndef SCM_DIGSTOOBIG
209 w
= scm_pseudolong(z
);
210 return scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), (SCM_BIGDIG
*)&w
, SCM_DIGSPERLONG
,
211 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
), zdigs
, SCM_DIGSPERLONG
,
216 SCM_BIGSIGN(x
) ? (y
>0) : (y
<0), 2);
222 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
223 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_quotient
);
228 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_quotient
);
229 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_quotient
);
231 if ((z
= SCM_INUM(y
))==0)
232 ov
: scm_num_overflow (s_quotient
);
237 long t
= ((y
<0) ? -SCM_INUM(x
) : SCM_INUM(x
))%SCM_INUM(y
);
239 long t
= SCM_INUM(x
)%SCM_INUM(y
);
250 return scm_long2big(z
);
252 scm_num_overflow (s_quotient
);
254 return SCM_MAKINUM(z
);
257 SCM_PROC(s_remainder
, "remainder", 2, 0, 0, scm_remainder
);
260 scm_remainder(SCM x
, SCM y
)
271 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_remainder
);
273 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
274 return scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
277 if (!(z
= SCM_INUM(y
))) goto ov
;
278 return scm_divbigint(x
, z
, SCM_BIGSIGN(x
), 0);
282 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
283 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_remainder
);
288 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_remainder
);
289 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_remainder
);
291 if (!(z
= SCM_INUM(y
)))
292 ov
: scm_num_overflow (s_remainder
);
301 else z
+= SCM_INUM(y
);
302 else if (x
< 0) z
-= SCM_INUM(y
);
304 return SCM_MAKINUM(z
);
307 SCM_PROC(s_modulo
, "modulo", 2, 0, 0, scm_modulo
);
310 scm_modulo(SCM x
, SCM y
)
321 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_modulo
);
323 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
324 return scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
325 SCM_BIGSIGN(y
), (SCM_BIGSIGN(x
) ^ SCM_BIGSIGN(y
)) ? 1 : 0);
327 if (!(z
= SCM_INUM(y
))) goto ov
;
328 return scm_divbigint(x
, z
, y
< 0, (SCM_BIGSIGN(x
) ? (y
> 0) : (y
< 0)) ? 1 : 0);
332 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
333 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_modulo
);
335 return (SCM_BIGSIGN(y
) ? (x
>0) : (x
<0)) ? scm_sum(x
, y
) : x
;
338 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_modulo
);
339 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_modulo
);
341 if (!(yy
= SCM_INUM(y
)))
342 ov
: scm_num_overflow (s_modulo
);
345 z
= ((yy
<0) ? -z
: z
)%yy
;
349 return SCM_MAKINUM(((yy
<0) ? (z
>0) : (z
<0)) ? z
+yy
: z
);
352 SCM_PROC1 (s_gcd
, "gcd", scm_tc7_asubr
, scm_gcd
);
355 scm_gcd(SCM x
, SCM y
)
363 register long u
, v
, k
, t
;
364 if SCM_UNBNDP(y
) return SCM_UNBNDP(x
) ? SCM_INUM0
: x
;
369 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_gcd
);
370 if SCM_BIGSIGN(x
) x
= scm_copybig(x
, 0);
373 SCM_ASSERT(SCM_NIMP(y
) && SCM_BIGP(y
), y
, SCM_ARG2
, s_gcd
);
374 if SCM_BIGSIGN(y
) y
= scm_copybig(y
, 0);
375 switch (scm_bigcomp(x
, y
)) {
377 swaprec
: t
= scm_remainder(x
, y
); x
= y
; y
= t
; goto tailrec
;
379 case 1: y
= scm_remainder(y
, x
); goto newy
;
381 /* instead of the switch, we could just return scm_gcd(y, scm_modulo(x, y)); */
383 if (SCM_INUM0
==y
) return x
; goto swaprec
;
385 if SCM_NINUMP(y
) { t
=x
; x
=y
; y
=t
; goto big_gcd
;}
387 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_gcd
);
388 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_gcd
);
394 else if (0==v
) goto getout
;
395 if (0==u
) {u
= v
; goto getout
;}
396 for (k
= 1;!(1 & ((int)u
|(int)v
));k
<<= 1, u
>>= 1, v
>>= 1);
397 if (1 & (int)u
) t
= -v
;
403 if (!(1 & (int)t
)) goto b3
;
406 if ((t
= u
-v
)) goto b3
;
409 if (!SCM_POSFIXABLE(u
))
411 return scm_long2big(u
);
413 scm_num_overflow (s_gcd
);
415 return SCM_MAKINUM(u
);
418 SCM_PROC1 (s_lcm
, "lcm", scm_tc7_asubr
, scm_lcm
);
421 scm_lcm(SCM n1
, SCM n2
)
431 n2
= SCM_MAKINUM(1L);
432 if SCM_UNBNDP(n1
) return n2
;
435 if (SCM_INUM0
==d
) return d
;
436 return scm_abs(scm_product(n1
, scm_quotient(n2
, d
)));
441 # define scm_long2num SCM_MAKINUM
446 SCM_PROC1 (s_logand
, "logand", scm_tc7_asubr
, scm_logand
);
449 scm_logand(SCM n1
, SCM n2
)
457 return scm_long2num(scm_num2long(n1
, (char *)SCM_ARG1
, s_logand
)
458 & scm_num2long(n2
, (char *)SCM_ARG2
, s_logand
));
461 SCM_PROC1 (s_logior
, "logior", scm_tc7_asubr
, scm_logior
);
464 scm_logior(SCM n1
, SCM n2
)
472 return scm_long2num(scm_num2long(n1
, (char *)SCM_ARG1
, s_logior
)
473 | scm_num2long(n2
, (char *)SCM_ARG2
, s_logior
));
476 SCM_PROC1 (s_logxor
, "logxor", scm_tc7_asubr
, scm_logxor
);
479 scm_logxor(SCM n1
, SCM n2
)
487 return scm_long2num(scm_num2long(n1
, (char *)SCM_ARG1
, s_logxor
)
488 ^ scm_num2long(n2
, (char *)SCM_ARG2
, s_logxor
));
491 SCM_PROC(s_logtest
, "logtest", 2, 0, 0, scm_logtest
);
494 scm_logtest(SCM n1
, SCM n2
)
502 return ((scm_num2long (n1
, (char *)SCM_ARG1
, s_logtest
)
503 & scm_num2long (n2
, (char *)SCM_ARG2
, s_logtest
))
504 ? SCM_BOOL_T
: SCM_BOOL_F
);
508 SCM_PROC(s_logbit_p
, "logbit?", 2, 0, 0, scm_logbit_p
);
511 scm_logbit_p(SCM n1
, SCM n2
)
519 return (((1 << scm_num2long (n1
, (char *)SCM_ARG1
, s_logtest
))
520 & scm_num2long (n2
, (char *)SCM_ARG2
, s_logtest
))
521 ? SCM_BOOL_T
: SCM_BOOL_F
);
526 SCM_PROC1 (s_logand
, "logand", scm_tc7_asubr
, scm_logand
);
529 scm_logand(SCM n1
, SCM n2
)
537 SCM_ASSERT(SCM_INUMP(n1
), n1
, SCM_ARG1
, s_logand
);
538 SCM_ASSERT(SCM_INUMP(n2
), n2
, SCM_ARG2
, s_logand
);
539 return SCM_MAKINUM(SCM_INUM(n1
) & SCM_INUM(n2
));
542 SCM_PROC1 (s_logior
, "logior", scm_tc7_asubr
, scm_logior
);
545 scm_logior(SCM n1
, SCM n2
)
553 SCM_ASSERT(SCM_INUMP(n1
), n1
, SCM_ARG1
, s_logior
);
554 SCM_ASSERT(SCM_INUMP(n2
), n2
, SCM_ARG2
, s_logior
);
555 return SCM_MAKINUM(SCM_INUM(n1
) | SCM_INUM(n2
));
558 SCM_PROC1 (s_logxor
, "logxor", scm_tc7_asubr
, scm_logxor
);
561 scm_logxor(SCM n1
, SCM n2
)
569 SCM_ASSERT(SCM_INUMP(n1
), n1
, SCM_ARG1
, s_logxor
);
570 SCM_ASSERT(SCM_INUMP(n2
), n2
, SCM_ARG2
, s_logxor
);
571 return SCM_MAKINUM(SCM_INUM(n1
) ^ SCM_INUM(n2
));
574 SCM_PROC(s_logtest
, "logtest", 2, 0, 0, scm_logtest
);
577 scm_logtest(SCM n1
, SCM n2
)
585 SCM_ASSERT(SCM_INUMP(n1
), n1
, SCM_ARG1
, s_logtest
);
586 SCM_ASSERT(SCM_INUMP(n2
), n2
, SCM_ARG2
, s_logtest
);
587 return (SCM_INUM(n1
) & SCM_INUM(n2
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
590 SCM_PROC(s_logbit_p
, "logbit?", 2, 0, 0, scm_logbit_p
);
593 scm_logbit_p(SCM n1
, SCM n2
)
601 SCM_ASSERT(SCM_INUMP(n1
) && SCM_INUM(n1
) >= 0, n1
, SCM_ARG1
, s_logbit_p
);
602 SCM_ASSERT(SCM_INUMP(n2
), n2
, SCM_ARG2
, s_logbit_p
);
603 return ((1 << SCM_INUM(n1
)) & SCM_INUM(n2
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
607 SCM_PROC(s_lognot
, "lognot", 1, 0, 0, scm_lognot
);
617 SCM_ASSERT(SCM_INUMP(n
), n
, SCM_ARG1
, s_lognot
);
618 return scm_difference(SCM_MAKINUM(-1L), n
);
621 SCM_PROC(s_integer_expt
, "integer-expt", 2, 0, 0, scm_integer_expt
);
624 scm_integer_expt(SCM z1
, SCM z2
)
627 scm_integer_expt(z1
, z2
)
632 SCM acc
= SCM_MAKINUM(1L);
634 if (SCM_INUM0
==z1
|| acc
==z1
) return z1
;
635 else if (SCM_MAKINUM(-1L)==z1
) return SCM_BOOL_F
==scm_even_p(z2
)?z1
:acc
;
637 SCM_ASSERT(SCM_INUMP(z2
), z2
, SCM_ARG2
, s_integer_expt
);
641 z1
= scm_divide(z1
, SCM_UNDEFINED
);
644 if (0==z2
) return acc
;
645 if (1==z2
) return scm_product(acc
, z1
);
646 if (z2
& 1) acc
= scm_product(acc
, z1
);
647 z1
= scm_product(z1
, z1
);
652 SCM_PROC(s_ash
, "ash", 2, 0, 0, scm_ash
);
655 scm_ash(SCM n
, SCM cnt
)
663 SCM res
= SCM_INUM(n
);
664 SCM_ASSERT(SCM_INUMP(cnt
), cnt
, SCM_ARG2
, s_ash
);
667 res
= scm_integer_expt(SCM_MAKINUM(2), SCM_MAKINUM(-SCM_INUM(cnt
)));
668 if (SCM_NFALSEP(scm_negative_p(n
)))
669 return scm_sum(SCM_MAKINUM(-1L), scm_quotient(scm_sum(SCM_MAKINUM(1L), n
), res
));
670 else return scm_quotient(n
, res
);
672 else return scm_product(n
, scm_integer_expt(SCM_MAKINUM(2), cnt
));
674 SCM_ASSERT(SCM_INUMP(n
), n
, SCM_ARG1
, s_ash
);
676 if (cnt
< 0) return SCM_MAKINUM(SCM_SRS(res
, -cnt
));
677 res
= SCM_MAKINUM(res
<<cnt
);
678 if (SCM_INUM(res
)>>cnt
!= SCM_INUM(n
))
679 scm_num_overflow (s_ash
);
684 SCM_PROC(s_bit_extract
, "bit-extract", 3, 0, 0, scm_bit_extract
);
687 scm_bit_extract(SCM n
, SCM start
, SCM end
)
690 scm_bit_extract(n
, start
, end
)
696 SCM_ASSERT(SCM_INUMP(start
), start
, SCM_ARG2
, s_bit_extract
);
697 SCM_ASSERT(SCM_INUMP(end
), end
, SCM_ARG3
, s_bit_extract
);
698 start
= SCM_INUM(start
); end
= SCM_INUM(end
);
699 SCM_ASSERT(end
>= start
, SCM_MAKINUM(end
), SCM_OUTOFRANGE
, s_bit_extract
);
703 scm_logand(scm_difference(scm_integer_expt(SCM_MAKINUM(2), SCM_MAKINUM(end
- start
)),
705 scm_ash(n
, SCM_MAKINUM(-start
)));
707 SCM_ASSERT(SCM_INUMP(n
), n
, SCM_ARG1
, s_bit_extract
);
709 return SCM_MAKINUM((SCM_INUM(n
)>>start
) & ((1L<<(end
-start
))-1));
712 char scm_logtab
[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
713 SCM_PROC(s_logcount
, "logcount", 1, 0, 0, scm_logcount
);
723 register unsigned long c
= 0;
727 scm_sizet i
; SCM_BIGDIG
*ds
, d
;
728 SCM_ASSERT(SCM_NIMP(n
) && SCM_BIGP(n
), n
, SCM_ARG1
, s_logcount
);
729 if SCM_BIGSIGN(n
) return scm_logcount(scm_difference(SCM_MAKINUM(-1L), n
));
731 for(i
= SCM_NUMDIGS(n
); i
--; )
732 for(d
= ds
[i
]; d
; d
>>= 4) c
+= scm_logtab
[15 & d
];
733 return SCM_MAKINUM(c
);
736 SCM_ASSERT(SCM_INUMP(n
), n
, SCM_ARG1
, s_logcount
);
738 if ((nn
= SCM_INUM(n
)) < 0) nn
= -1 - nn
;
739 for(; nn
; nn
>>= 4) c
+= scm_logtab
[15 & nn
];
740 return SCM_MAKINUM(c
);
743 char scm_ilentab
[] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4};
744 SCM_PROC(s_integer_length
, "integer-length", 1, 0, 0, scm_integer_length
);
747 scm_integer_length(SCM n
)
750 scm_integer_length(n
)
754 register unsigned long c
= 0;
760 SCM_ASSERT(SCM_NIMP(n
) && SCM_BIGP(n
), n
, SCM_ARG1
, s_integer_length
);
761 if SCM_BIGSIGN(n
) return scm_integer_length(scm_difference(SCM_MAKINUM(-1L), n
));
763 d
= ds
[c
= SCM_NUMDIGS(n
)-1];
764 for(c
*= SCM_BITSPERDIG
; d
; d
>>= 4) {c
+= 4; l
= scm_ilentab
[15 & d
];}
765 return SCM_MAKINUM(c
- 4 + l
);
768 SCM_ASSERT(SCM_INUMP(n
), n
, SCM_ARG1
, s_integer_length
);
770 if ((nn
= SCM_INUM(n
)) < 0) nn
= -1 - nn
;
771 for(;nn
; nn
>>= 4) {c
+= 4; l
= scm_ilentab
[15 & nn
];}
772 return SCM_MAKINUM(c
- 4 + l
);
777 char s_bignum
[] = "bignum";
780 scm_mkbig(scm_sizet nlen
, int sign
)
783 scm_mkbig(nlen
, sign
)
789 if (((v
<< 16) >> 16) != nlen
)
790 scm_wta(SCM_MAKINUM(nlen
), (char *)SCM_NALLOC
, s_bignum
);
793 SCM_SETCHARS(v
, scm_must_malloc((long)(nlen
*sizeof(SCM_BIGDIG
)), s_bignum
));
794 SCM_SETNUMDIGS(v
, nlen
, sign
?scm_tc16_bigneg
:scm_tc16_bigpos
);
801 scm_big2inum(SCM b
, scm_sizet l
)
809 unsigned long num
= 0;
810 SCM_BIGDIG
*tmp
= SCM_BDIGITS(b
);
811 while (l
--) num
= SCM_BIGUP(num
) + tmp
[l
];
812 if (SCM_TYP16(b
)==scm_tc16_bigpos
) {
813 if SCM_POSFIXABLE(num
) return SCM_MAKINUM(num
);
815 else if SCM_UNEGFIXABLE(num
) return SCM_MAKINUM(-num
);
820 char s_adjbig
[] = "scm_adjbig";
823 scm_adjbig(SCM b
, scm_sizet nlen
)
832 if (((nsiz
<< 16) >> 16) != nlen
) scm_wta(SCM_MAKINUM(nsiz
), (char *)SCM_NALLOC
, s_adjbig
);
834 SCM_SETCHARS(b
, (SCM_BIGDIG
*)scm_must_realloc((char *)SCM_CHARS(b
),
835 (long)(SCM_NUMDIGS(b
)*sizeof(SCM_BIGDIG
)),
836 (long)(nsiz
*sizeof(SCM_BIGDIG
)), s_adjbig
));
837 SCM_SETNUMDIGS(b
, nsiz
, SCM_TYP16(b
));
853 scm_sizet nlen
= SCM_NUMDIGS(b
);
855 int nlen
= SCM_NUMDIGS(b
); /* unsigned nlen breaks on Cray when nlen => 0 */
857 SCM_BIGDIG
*zds
= SCM_BDIGITS(b
);
858 while (nlen
-- && !zds
[nlen
]); nlen
++;
859 if (nlen
* SCM_BITSPERDIG
/SCM_CHAR_BIT
<= sizeof(SCM
))
860 if SCM_INUMP(b
= scm_big2inum(b
, (scm_sizet
)nlen
)) return b
;
861 if (SCM_NUMDIGS(b
)==nlen
) return b
;
862 return scm_adjbig(b
, (scm_sizet
)nlen
);
868 scm_copybig(SCM b
, int sign
)
876 scm_sizet i
= SCM_NUMDIGS(b
);
877 SCM ans
= scm_mkbig(i
, sign
);
878 SCM_BIGDIG
*src
= SCM_BDIGITS(b
), *dst
= SCM_BDIGITS(ans
);
879 while (i
--) dst
[i
] = src
[i
];
895 SCM ans
= scm_mkbig(SCM_DIGSPERLONG
, n
<0);
896 digits
= SCM_BDIGITS(ans
);
898 while (i
< SCM_DIGSPERLONG
) {
899 digits
[i
++] = SCM_BIGLO(n
);
900 n
= SCM_BIGDN((unsigned long)n
);
908 scm_long_long2big(long_long n
)
923 if ((long long)tn
== n
)
924 return scm_long2big (tn
);
930 for (tn
= n
, n_digits
= 0;
932 ++n_digits
, tn
= SCM_BIGDN ((ulong_long
)tn
))
937 ans
= scm_mkbig(n_digits
, n
<0);
938 digits
= SCM_BDIGITS(ans
);
941 while (i
< n_digits
) {
942 digits
[i
++] = SCM_BIGLO(n
);
943 n
= SCM_BIGDN((ulong_long
)n
);
951 scm_2ulong2big(unsigned long * np
)
963 ans
= scm_mkbig(2 * SCM_DIGSPERLONG
, 0);
964 digits
= SCM_BDIGITS(ans
);
967 for (i
= 0; i
< SCM_DIGSPERLONG
; ++i
)
969 digits
[i
] = SCM_BIGLO(n
);
970 n
= SCM_BIGDN((unsigned long)n
);
973 for (i
= 0; i
< SCM_DIGSPERLONG
; ++i
)
975 digits
[i
+ SCM_DIGSPERLONG
] = SCM_BIGLO(n
);
976 n
= SCM_BIGDN((unsigned long)n
);
984 scm_ulong2big(unsigned long n
)
993 SCM ans
= scm_mkbig(SCM_DIGSPERLONG
, 0);
994 digits
= SCM_BDIGITS(ans
);
995 while (i
< SCM_DIGSPERLONG
) {
996 digits
[i
++] = SCM_BIGLO(n
);
1005 scm_bigcomp(SCM x
, SCM y
)
1013 int xsign
= SCM_BIGSIGN(x
);
1014 int ysign
= SCM_BIGSIGN(y
);
1015 scm_sizet xlen
, ylen
;
1016 if (ysign
< xsign
) return 1;
1017 if (ysign
> xsign
) return -1;
1018 if ((ylen
= SCM_NUMDIGS(y
)) > (xlen
= SCM_NUMDIGS(x
))) return (xsign
) ? -1 : 1;
1019 if (ylen
< xlen
) return (xsign
) ? 1 : -1;
1020 while(xlen
-- && (SCM_BDIGITS(y
)[xlen
]==SCM_BDIGITS(x
)[xlen
]));
1021 if (-1==xlen
) return 0;
1022 return (SCM_BDIGITS(y
)[xlen
] > SCM_BDIGITS(x
)[xlen
]) ?
1023 (xsign
? -1 : 1) : (xsign
? 1 : -1);
1026 #ifndef SCM_DIGSTOOBIG
1030 scm_pseudolong(long x
)
1039 SCM_BIGDIG bd
[SCM_DIGSPERLONG
];
1043 while (i
< SCM_DIGSPERLONG
) {p
.bd
[i
++] = SCM_BIGLO(x
); x
= SCM_BIGDN(x
);}
1044 /* p.bd[0] = SCM_BIGLO(x); p.bd[1] = SCM_BIGDN(x); */
1052 scm_longdigs(long x
, SCM_BIGDIG digs
[])
1055 scm_longdigs(x
, digs
)
1062 while (i
< SCM_DIGSPERLONG
) {digs
[i
++] = SCM_BIGLO(x
); x
= SCM_BIGDN(x
);}
1069 scm_addbig(SCM_BIGDIG
*x
, scm_sizet nx
, int xsgn
, SCM bigy
, int sgny
)
1072 scm_addbig(x
, nx
, xsgn
, bigy
, sgny
)
1080 /* Assumes nx <= SCM_NUMDIGS(bigy) */
1081 /* Assumes xsgn and sgny scm_equal either 0 or 0x0100 */
1083 scm_sizet i
= 0, ny
= SCM_NUMDIGS(bigy
);
1084 SCM z
= scm_copybig(bigy
, SCM_BIGSIGN(bigy
) ^ sgny
);
1085 SCM_BIGDIG
*zds
= SCM_BDIGITS(z
);
1086 if (xsgn
^ SCM_BIGSIGN(z
)) {
1088 num
+= (long) zds
[i
] - x
[i
];
1089 if (num
< 0) {zds
[i
] = num
+ SCM_BIGRAD
; num
= -1;}
1090 else {zds
[i
] = SCM_BIGLO(num
); num
= 0;}
1092 if (num
&& nx
==ny
) {
1094 SCM_CAR(z
) ^= 0x0100;
1096 num
+= (SCM_BIGRAD
-1) - zds
[i
];
1097 zds
[i
++] = SCM_BIGLO(num
);
1098 num
= SCM_BIGDN(num
);
1101 else while (i
< ny
) {
1103 if (num
< 0) {zds
[i
++] = num
+ SCM_BIGRAD
; num
= -1;}
1104 else {zds
[i
++] = SCM_BIGLO(num
); num
= 0;}
1108 num
+= (long) zds
[i
] + x
[i
];
1109 zds
[i
++] = SCM_BIGLO(num
);
1110 num
= SCM_BIGDN(num
);
1115 zds
[i
++] = SCM_BIGLO(num
);
1116 num
= SCM_BIGDN(num
);
1119 if (num
) {z
= scm_adjbig(z
, ny
+1); SCM_BDIGITS(z
)[ny
] = num
; return z
;}
1121 return scm_normbig(z
);
1126 scm_mulbig(SCM_BIGDIG
*x
, scm_sizet nx
, SCM_BIGDIG
*y
, scm_sizet ny
, int sgn
)
1129 scm_mulbig(x
, nx
, y
, ny
, sgn
)
1137 scm_sizet i
= 0, j
= nx
+ ny
;
1138 unsigned long n
= 0;
1139 SCM z
= scm_mkbig(j
, sgn
);
1140 SCM_BIGDIG
*zds
= SCM_BDIGITS(z
);
1141 while (j
--) zds
[j
] = 0;
1146 n
+= zds
[i
+ j
] + ((unsigned long) x
[i
] * y
[j
]);
1147 zds
[i
+ j
++] = SCM_BIGLO(n
);
1150 if (n
) {zds
[i
+ j
] = n
; n
= 0;}
1153 return scm_normbig(z
);
1158 scm_divbigdig(SCM_BIGDIG
*ds
, scm_sizet h
, SCM_BIGDIG div
)
1161 scm_divbigdig(ds
, h
, div
)
1167 register unsigned long t2
= 0;
1169 t2
= SCM_BIGUP(t2
) + ds
[h
];
1179 scm_divbigint(SCM x
, long z
, int sgn
, int mode
)
1182 scm_divbigint(x
, z
, sgn
, mode
)
1190 if (z
< SCM_BIGRAD
) {
1191 register unsigned long t2
= 0;
1192 register SCM_BIGDIG
*ds
= SCM_BDIGITS(x
);
1193 scm_sizet nd
= SCM_NUMDIGS(x
);
1194 while(nd
--) t2
= (SCM_BIGUP(t2
) + ds
[nd
]) % z
;
1195 if (mode
) t2
= z
- t2
;
1196 return SCM_MAKINUM(sgn
? -t2
: t2
);
1199 #ifndef SCM_DIGSTOOBIG
1200 unsigned long t2
= scm_pseudolong(z
);
1201 return scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), (SCM_BIGDIG
*)&t2
,
1202 SCM_DIGSPERLONG
, sgn
, mode
);
1204 SCM_BIGDIG t2
[SCM_DIGSPERLONG
];
1205 scm_longdigs(z
, t2
);
1206 return scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), t2
, SCM_DIGSPERLONG
, sgn
, mode
);
1213 scm_divbigbig(SCM_BIGDIG
*x
, scm_sizet nx
, SCM_BIGDIG
*y
, scm_sizet ny
, int sgn
, int modes
)
1216 scm_divbigbig(x
, nx
, y
, ny
, sgn
, modes
)
1225 /* modes description
1229 3 quotient but returns 0 if division is not exact. */
1230 scm_sizet i
= 0, j
= 0;
1232 unsigned long t2
= 0;
1234 SCM_BIGDIG d
= 0, qhat
, *zds
, *yds
;
1235 /* algorithm requires nx >= ny */
1238 case 0: /* remainder -- just return x */
1239 z
= scm_mkbig(nx
, sgn
); zds
= SCM_BDIGITS(z
);
1240 do {zds
[i
] = x
[i
];} while (++i
< nx
);
1242 case 1: /* scm_modulo -- return y-x */
1243 z
= scm_mkbig(ny
, sgn
); zds
= SCM_BDIGITS(z
);
1245 num
+= (long) y
[i
] - x
[i
];
1246 if (num
< 0) {zds
[i
] = num
+ SCM_BIGRAD
; num
= -1;}
1247 else {zds
[i
] = num
; num
= 0;}
1251 if (num
< 0) {zds
[i
++] = num
+ SCM_BIGRAD
; num
= -1;}
1252 else {zds
[i
++] = num
; num
= 0;}
1255 case 2: return SCM_INUM0
; /* quotient is zero */
1256 case 3: return 0; /* the division is not exact */
1259 z
= scm_mkbig(nx
==ny
? nx
+2 : nx
+1, sgn
); zds
= SCM_BDIGITS(z
);
1260 if (nx
==ny
) zds
[nx
+1] = 0;
1261 while(!y
[ny
-1]) ny
--; /* in case y came in as a psuedolong */
1262 if (y
[ny
-1] < (SCM_BIGRAD
>>1)) { /* normalize operands */
1263 d
= SCM_BIGRAD
/(y
[ny
-1]+1);
1264 newy
= scm_mkbig(ny
, 0); yds
= SCM_BDIGITS(newy
);
1266 {t2
+= (unsigned long) y
[j
]*d
; yds
[j
++] = SCM_BIGLO(t2
); t2
= SCM_BIGDN(t2
);}
1267 y
= yds
; j
= 0; t2
= 0;
1269 {t2
+= (unsigned long) x
[j
]*d
; zds
[j
++] = SCM_BIGLO(t2
); t2
= SCM_BIGDN(t2
);}
1272 else {zds
[j
= nx
] = 0; while (j
--) zds
[j
] = x
[j
];}
1273 j
= nx
==ny
? nx
+1 : nx
; /* dividend needs more digits than divisor */
1274 do { /* loop over digits of quotient */
1275 if (zds
[j
]==y
[ny
-1]) qhat
= SCM_BIGRAD
-1;
1276 else qhat
= (SCM_BIGUP(zds
[j
]) + zds
[j
-1])/y
[ny
-1];
1277 if (!qhat
) continue;
1278 i
= 0; num
= 0; t2
= 0;
1279 do { /* multiply and subtract */
1280 t2
+= (unsigned long) y
[i
] * qhat
;
1281 num
+= zds
[j
- ny
+ i
] - SCM_BIGLO(t2
);
1282 if (num
< 0) {zds
[j
- ny
+ i
] = num
+ SCM_BIGRAD
; num
= -1;}
1283 else {zds
[j
- ny
+ i
] = num
; num
= 0;}
1286 num
+= zds
[j
- ny
+ i
] - t2
; /* borrow from high digit; don't update */
1287 while (num
) { /* "add back" required */
1288 i
= 0; num
= 0; qhat
--;
1290 num
+= (long) zds
[j
- ny
+ i
] + y
[i
];
1291 zds
[j
- ny
+ i
] = SCM_BIGLO(num
);
1292 num
= SCM_BIGDN(num
);
1296 if (modes
& 2) zds
[j
] = qhat
;
1297 } while (--j
>= ny
);
1299 case 3: /* check that remainder==0 */
1300 for(j
= ny
;j
&& !zds
[j
-1];--j
) ; if (j
) return 0;
1301 case 2: /* move quotient down in z */
1302 j
= (nx
==ny
? nx
+2 : nx
+1) - ny
;
1303 for (i
= 0;i
< j
;i
++) zds
[i
] = zds
[i
+ny
];
1306 case 1: /* subtract for scm_modulo */
1307 i
= 0; num
= 0; j
= 0;
1308 do {num
+= y
[i
] - zds
[i
];
1310 if (num
< 0) {zds
[i
] = num
+ SCM_BIGRAD
; num
= -1;}
1311 else {zds
[i
] = num
; num
= 0;}
1313 if (!j
) return SCM_INUM0
;
1314 case 0: /* just normalize remainder */
1315 if (d
) scm_divbigdig(zds
, ny
, d
);
1318 for(j
= ny
;j
&& !zds
[j
-1];--j
) ;
1319 if (j
* SCM_BITSPERDIG
<= sizeof(SCM
)*SCM_CHAR_BIT
)
1320 if SCM_INUMP(z
= scm_big2inum(z
, j
)) return z
;
1321 return scm_adjbig(z
, j
);
1329 /*** NUMBERS -> STRINGS ***/
1332 static double fx
[] = {0.0, 5e-1, 5e-2, 5e-3, 5e-4, 5e-5,
1333 5e-6, 5e-7, 5e-8, 5e-9, 5e-10,
1334 5e-11,5e-12,5e-13,5e-14,5e-15,
1335 5e-16,5e-17,5e-18,5e-19,5e-20};
1341 idbl2str(double f
, char *a
)
1349 int efmt
, dpt
, d
, i
, wp
= scm_dblprec
;
1353 if (f
== 0.0) goto zero
; /*{a[0]='0'; a[1]='.'; a[2]='0'; return 3;}*/
1354 if (f
< 0.0) {f
= -f
;a
[ch
++]='-';}
1359 if (ch
== 0) a
[ch
++]='+';
1360 funny
: a
[ch
++]='#'; a
[ch
++]='.'; a
[ch
++]='#'; return ch
;
1362 # ifdef DBL_MIN_10_EXP /* Prevent unnormalized values, as from
1363 make-uniform-vector, from causing infinite loops. */
1364 while (f
< 1.0) {f
*= 10.0; if (exp
-- < DBL_MIN_10_EXP
) goto funny
;}
1365 while (f
> 10.0) {f
*= 0.10; if (exp
++ > DBL_MAX_10_EXP
) goto funny
;}
1367 while (f
< 1.0) {f
*= 10.0; exp
--;}
1368 while (f
> 10.0) {f
/= 10.0; exp
++;}
1370 if (f
+fx
[wp
] >= 10.0) {f
= 1.0; exp
++;}
1377 efmt
= (exp
< -3) || (exp
> wp
+2);
1383 while (++dpt
) a
[ch
++] = '0';
1394 if (f
< fx
[wp
]) break;
1395 if (f
+fx
[wp
] >= 1.0) {
1400 if (!(--dpt
)) a
[ch
++] = '.';
1405 if ((dpt
> 4) && (exp
> 6)) {
1406 d
= (a
[0]=='-'?2:1);
1407 for (i
= ch
++; i
> d
; i
--)
1414 while (--dpt
) a
[ch
++] = '0';
1417 if (a
[ch
-1]=='.') a
[ch
++]='0'; /* trailing zero */
1424 for (i
= 10; i
<= exp
; i
*= 10);
1425 for (i
/= 10; i
; i
/= 10) {
1426 a
[ch
++] = exp
/i
+ '0';
1435 iflo2str(SCM flt
, char *str
)
1445 if SCM_SINGP(flt
) i
= idbl2str(SCM_FLO(flt
), str
);
1448 i
= idbl2str(SCM_REAL(flt
), str
);
1450 if(0 <= SCM_IMAG(flt
)) /* jeh */
1451 str
[i
++] = '+'; /* jeh */
1452 i
+= idbl2str(SCM_IMAG(flt
), &str
[i
]);
1457 #endif /* SCM_FLOATS */
1461 scm_iint2str(long num
, int rad
, char *p
)
1464 scm_iint2str(num
, rad
, p
)
1471 register int i
= 1, d
;
1472 register long n
= num
;
1473 if (n
< 0) {n
= -n
; i
++;}
1474 for (n
/= rad
;n
> 0;n
/= rad
) i
++;
1477 if (n
< 0) {n
= -n
; *p
++ = '-'; i
--;}
1481 p
[i
] = d
+ ((d
< 10) ? '0' : 'a' - 10);
1490 big2str(SCM b
, register unsigned int radix
)
1495 register unsigned int radix
;
1498 SCM t
= scm_copybig(b
, 0); /* sign of temp doesn't matter */
1499 register SCM_BIGDIG
*ds
= SCM_BDIGITS(t
);
1500 scm_sizet i
= SCM_NUMDIGS(t
);
1501 scm_sizet j
= radix
==16 ? (SCM_BITSPERDIG
*i
)/4+2
1502 : radix
>= 10 ? (SCM_BITSPERDIG
*i
*241L)/800+2
1503 : (SCM_BITSPERDIG
*i
)+2;
1505 scm_sizet radct
= 0;
1506 scm_sizet ch
; /* jeh */
1507 SCM_BIGDIG radpow
= 1, radmod
= 0;
1508 SCM ss
= scm_makstr((long)j
, 0);
1509 char *s
= SCM_CHARS(ss
), c
;
1510 while ((long) radpow
* radix
< SCM_BIGRAD
) {
1514 s
[0] = scm_tc16_bigneg
==SCM_TYP16(b
) ? '-' : '+';
1515 while ((i
|| radmod
) && j
) {
1517 radmod
= (SCM_BIGDIG
)scm_divbigdig(ds
, i
, radpow
);
1521 c
= radmod
% radix
; radmod
/= radix
; k
--;
1522 s
[--j
] = c
< 10 ? c
+ '0' : c
+ 'a' - 10;
1524 ch
= s
[0] == '-' ? 1 : 0; /* jeh */
1525 if (ch
< j
) { /* jeh */
1526 for(i
= j
;j
< SCM_LENGTH(ss
);j
++) s
[ch
+j
-i
] = s
[j
]; /* jeh */
1527 scm_vector_set_length_x(ss
, (SCM
)SCM_MAKINUM(ch
+SCM_LENGTH(ss
)-i
)); /* jeh */
1534 SCM_PROC(s_number_to_string
, "number->string", 1, 1, 0, scm_number_to_string
);
1537 scm_number_to_string(SCM x
, SCM radix
)
1540 scm_number_to_string(x
, radix
)
1545 if SCM_UNBNDP(radix
) radix
=SCM_MAKINUM(10L);
1546 else SCM_ASSERT(SCM_INUMP(radix
), radix
, SCM_ARG2
, s_number_to_string
);
1549 char num_buf
[SCM_FLOBUFLEN
];
1551 SCM_ASRTGO(SCM_NIMP(x
), badx
);
1552 if SCM_BIGP(x
) return big2str(x
, (unsigned int)SCM_INUM(radix
));
1554 if (!(SCM_INEXP(x
)))
1555 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_number_to_string
);
1558 SCM_ASSERT(SCM_NIMP(x
) && SCM_INEXP(x
), x
, SCM_ARG1
, s_number_to_string
);
1560 return scm_makfromstr(num_buf
, iflo2str(x
, num_buf
), 0);
1565 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_number_to_string
);
1566 return big2str(x
, (unsigned int)SCM_INUM(radix
));
1569 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_number_to_string
);
1573 char num_buf
[SCM_INTBUFLEN
];
1574 return scm_makfromstr(num_buf
,
1575 scm_iint2str(SCM_INUM(x
), (int)SCM_INUM(radix
), num_buf
), 0);
1580 /* These print routines are stubbed here so that scm_repl.c doesn't need
1581 SCM_FLOATS or SCM_BIGDIGs conditionals */
1584 scm_floprint(SCM sexp
, SCM port
, int writing
)
1587 scm_floprint(sexp
, port
, writing
)
1594 char num_buf
[SCM_FLOBUFLEN
];
1595 scm_gen_write (scm_regular_string
, num_buf
, iflo2str(sexp
, num_buf
), port
);
1597 scm_ipruk("float", sexp
, port
);
1605 scm_bigprint(SCM exp
, SCM port
, int writing
)
1608 scm_bigprint(exp
, port
, writing
)
1615 exp
= big2str(exp
, (unsigned int)10);
1616 scm_gen_write (scm_regular_string
, SCM_CHARS(exp
), (scm_sizet
)SCM_LENGTH(exp
), port
);
1618 scm_ipruk("bignum", exp
, port
);
1622 /*** END nums->strs ***/
1624 /*** STRINGS -> NUMBERS ***/
1628 scm_istr2int(char *str
, long len
, long radix
)
1631 scm_istr2int(str
, len
, radix
)
1638 register scm_sizet k
, blen
= 1;
1642 register SCM_BIGDIG
*ds
;
1643 register unsigned long t2
;
1645 if (0 >= len
) return SCM_BOOL_F
; /* zero scm_length */
1646 if (16==radix
) j
= 1+(4*len
*sizeof(char))/(SCM_BITSPERDIG
);
1647 else if (10 <= radix
)
1648 j
= 1+(84*len
*sizeof(char))/(SCM_BITSPERDIG
*25);
1649 else j
= 1+(len
*sizeof(char))/(SCM_BITSPERDIG
);
1650 switch (str
[0]) { /* leading sign */
1652 case '+': if (++i
==len
) return SCM_BOOL_F
; /* bad if lone `+' or `-' */
1654 res
= scm_mkbig(j
, '-'==str
[0]);
1655 ds
= SCM_BDIGITS(res
);
1656 for (k
= j
;k
--;) ds
[k
] = 0;
1658 switch (c
= str
[i
++]) {
1662 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1665 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1668 if (c
>= radix
) return SCM_BOOL_F
; /* bad digit for radix */
1673 /* printf("k = %d, blen = %d, t2 = %ld, ds[k] = %d\n", k, blen, t2, ds[k]);*/
1675 ds
[k
++] = SCM_BIGLO(t2
);
1679 scm_num_overflow ("bignum");
1680 if (t2
) {blen
++; goto moretodo
;}
1683 return SCM_BOOL_F
; /* not a digit */
1686 if (blen
* SCM_BITSPERDIG
/SCM_CHAR_BIT
<= sizeof(SCM
))
1687 if SCM_INUMP(res
= scm_big2inum(res
, blen
)) return res
;
1688 if (j
==blen
) return res
;
1689 return scm_adjbig(res
, blen
);
1697 scm_istr2int(char *str
, long len
, long radix
)
1700 scm_istr2int(str
, len
, radix
)
1706 register long n
= 0, ln
;
1710 if (0 >= len
) return SCM_BOOL_F
; /* zero scm_length */
1711 switch (*str
) { /* leading sign */
1712 case '-': lead_neg
= 1;
1713 case '+': if (++i
==len
) return SCM_BOOL_F
; /* bad if lone `+' or `-' */
1717 switch (c
= str
[i
++]) {
1721 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1724 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1727 if (c
>= radix
) return SCM_BOOL_F
; /* bad digit for radix */
1730 /* Negation is a workaround for HP700 cc bug */
1731 if (n
> ln
|| (-n
> -SCM_MOST_NEGATIVE_FIXNUM
)) goto ovfl
;
1734 return SCM_BOOL_F
; /* not a digit */
1737 if (!lead_neg
) if ((n
= -n
) > SCM_MOST_POSITIVE_FIXNUM
) goto ovfl
;
1738 return SCM_MAKINUM(n
);
1739 ovfl
: /* overflow scheme integer */
1747 scm_istr2flo(char *str
, long len
, long radix
)
1750 scm_istr2flo(str
, len
, radix
)
1756 register int c
, i
= 0;
1758 double res
= 0.0, tmp
= 0.0;
1763 if (i
>= len
) return SCM_BOOL_F
; /* zero scm_length */
1765 switch (*str
) { /* leading sign */
1766 case '-': lead_sgn
= -1.0; i
++; break;
1767 case '+': lead_sgn
= 1.0; i
++; break;
1768 default : lead_sgn
= 0.0;
1770 if (i
==len
) return SCM_BOOL_F
; /* bad if lone `+' or `-' */
1772 if (str
[i
]=='i' || str
[i
]=='I') { /* handle `+i' and `-i' */
1773 if (lead_sgn
==0.0) return SCM_BOOL_F
; /* must have leading sign */
1774 if (++i
< len
) return SCM_BOOL_F
; /* `i' not last character */
1775 return scm_makdbl(0.0, lead_sgn
);
1777 do { /* check initial digits */
1778 switch (c
= str
[i
]) {
1782 case 'D': case 'E': case 'F':
1783 if (radix
==10) goto out1
; /* must be exponent */
1784 case 'A': case 'B': case 'C':
1787 case 'd': case 'e': case 'f':
1788 if (radix
==10) goto out1
;
1789 case 'a': case 'b': case 'c':
1792 if (c
>= radix
) return SCM_BOOL_F
; /* bad digit for radix */
1793 res
= res
* radix
+ c
;
1794 flg
= 1; /* res is valid */
1799 } while (++i
< len
);
1802 /* if true, then we did see a digit above, and res is valid */
1803 if (i
==len
) goto done
;
1805 /* By here, must have seen a digit,
1806 or must have next char be a `.' with radix==10 */
1808 if (!(str
[i
]=='.' && radix
==10))
1811 while (str
[i
]=='#') { /* optional sharps */
1813 if (++i
==len
) goto done
;
1818 switch (c
= str
[i
]) {
1822 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1825 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1828 if (c
>= radix
) return SCM_BOOL_F
;
1829 tmp
= tmp
* radix
+ c
;
1836 if (tmp
==0.0) return SCM_BOOL_F
; /* `slash zero' not allowed */
1838 while (str
[i
]=='#') { /* optional sharps */
1840 if (++i
==len
) break;
1846 if (str
[i
]=='.') { /* decimal point notation */
1847 if (radix
!= 10) return SCM_BOOL_F
; /* must be radix 10 */
1849 switch (c
= str
[i
]) {
1852 res
= res
*10.0 + c
-'0';
1860 if (!flg
) return SCM_BOOL_F
; /* no digits before or after decimal point */
1861 if (i
==len
) goto adjust
;
1862 while (str
[i
]=='#') { /* ignore remaining sharps */
1863 if (++i
==len
) goto adjust
;
1867 switch (str
[i
]) { /* exponent */
1872 case 's': case 'S': {
1873 int expsgn
= 1, expon
= 0;
1874 if (radix
!= 10) return SCM_BOOL_F
; /* only in radix 10 */
1875 if (++i
==len
) return SCM_BOOL_F
; /* bad exponent */
1877 case '-': expsgn
=(-1);
1878 case '+': if (++i
==len
) return SCM_BOOL_F
; /* bad exponent */
1880 if (str
[i
] < '0' || str
[i
] > '9') return SCM_BOOL_F
; /* bad exponent */
1882 switch (c
= str
[i
]) {
1884 expon
= expon
*10 + c
-'0';
1885 if (expon
> MAXEXP
) return SCM_BOOL_F
; /* exponent too large */
1890 } while (++i
< len
);
1892 point
+= expsgn
*expon
;
1898 while (point
--) res
*= 10.0;
1901 while (point
++) res
*= 0.1;
1903 while (point
++) res
/= 10.0;
1907 /* at this point, we have a legitimate floating point result */
1908 if (lead_sgn
==-1.0) res
= -res
;
1909 if (i
==len
) return scm_makdbl(res
, 0.0);
1911 if (str
[i
]=='i' || str
[i
]=='I') { /* pure imaginary number */
1912 if (lead_sgn
==0.0) return SCM_BOOL_F
; /* must have leading sign */
1913 if (++i
< len
) return SCM_BOOL_F
; /* `i' not last character */
1914 return scm_makdbl(0.0, res
);
1918 case '-': lead_sgn
= -1.0; break;
1919 case '+': lead_sgn
= 1.0; break;
1920 case '@': { /* polar input for complex number */
1921 /* get a `real' for scm_angle */
1922 second
= scm_istr2flo(&str
[i
], (long)(len
-i
), radix
);
1923 if (!(SCM_INEXP(second
))) return SCM_BOOL_F
; /* not `real' */
1924 if (SCM_CPLXP(second
)) return SCM_BOOL_F
; /* not `real' */
1925 tmp
= SCM_REALPART(second
);
1926 return scm_makdbl(res
*cos(tmp
), res
*sin(tmp
));
1928 default: return SCM_BOOL_F
;
1931 /* at this point, last char must be `i' */
1932 if (str
[len
-1] != 'i' && str
[len
-1] != 'I') return SCM_BOOL_F
;
1933 /* handles `x+i' and `x-i' */
1934 if (i
==(len
-1)) return scm_makdbl(res
, lead_sgn
);
1935 /* get a `ureal' for complex part */
1936 second
= scm_istr2flo(&str
[i
], (long)((len
-i
)-1), radix
);
1937 if (!(SCM_INEXP(second
))) return SCM_BOOL_F
; /* not `ureal' */
1938 if (SCM_CPLXP(second
)) return SCM_BOOL_F
; /* not `ureal' */
1939 tmp
= SCM_REALPART(second
);
1940 if (tmp
< 0.0) return SCM_BOOL_F
; /* not `ureal' */
1941 return scm_makdbl(res
, (lead_sgn
*tmp
));
1943 #endif /* SCM_FLOATS */
1948 scm_istring2number(char *str
, long len
, long radix
)
1951 scm_istring2number(str
, len
, radix
)
1959 char ex_p
= 0, rx_p
= 0; /* Only allow 1 exactness and 1 radix prefix */
1962 if (*str
=='+' || *str
=='-') /* Catches lone `+' and `-' for speed */
1965 while ((len
-i
) >= 2 && str
[i
]=='#' && ++i
)
1967 case 'b': case 'B': if (rx_p
++) return SCM_BOOL_F
; radix
= 2; break;
1968 case 'o': case 'O': if (rx_p
++) return SCM_BOOL_F
; radix
= 8; break;
1969 case 'd': case 'D': if (rx_p
++) return SCM_BOOL_F
; radix
= 10; break;
1970 case 'x': case 'X': if (rx_p
++) return SCM_BOOL_F
; radix
= 16; break;
1971 case 'i': case 'I': if (ex_p
++) return SCM_BOOL_F
; ex
= 2; break;
1972 case 'e': case 'E': if (ex_p
++) return SCM_BOOL_F
; ex
= 1; break;
1973 default: return SCM_BOOL_F
;
1978 return scm_istr2int(&str
[i
], len
-i
, radix
);
1980 res
= scm_istr2int(&str
[i
], len
-i
, radix
);
1981 if SCM_NFALSEP(res
) return res
;
1983 case 2: return scm_istr2flo(&str
[i
], len
-i
, radix
);
1990 SCM_PROC(s_string_to_number
, "string->number", 1, 1, 0, scm_string_to_number
);
1993 scm_string_to_number(SCM str
, SCM radix
)
1996 scm_string_to_number(str
, radix
)
2002 if SCM_UNBNDP(radix
) radix
=SCM_MAKINUM(10L);
2003 else SCM_ASSERT(SCM_INUMP(radix
), radix
, SCM_ARG2
, s_string_to_number
);
2004 SCM_ASSERT(SCM_NIMP(str
) && SCM_ROSTRINGP(str
), str
, SCM_ARG1
, s_string_to_number
);
2005 answer
= scm_istring2number(SCM_ROCHARS(str
), SCM_ROLENGTH(str
), SCM_INUM(radix
));
2006 return scm_return_first (answer
, str
);
2008 /*** END strs->nums ***/
2013 scm_makdbl (double x
, double y
)
2022 if ((y
==0.0) && (x
==0.0)) return scm_flo0
;
2028 # ifndef SCM_SINGLESONLY
2029 if ((-FLTMAX
< x
) && (x
< FLTMAX
) && (fx
==x
))
2032 SCM_CAR(z
) = scm_tc_flo
;
2037 # endif/* def SCM_SINGLES */
2038 SCM_CDR(z
) = (SCM
)scm_must_malloc(1L*sizeof(double), "real");
2039 SCM_CAR(z
) = scm_tc_dblr
;
2042 SCM_CDR(z
) = (SCM
)scm_must_malloc(2L*sizeof(double), "complex");
2043 SCM_CAR(z
) = scm_tc_dblc
;
2055 scm_bigequal(SCM x
, SCM y
)
2064 if (0==scm_bigcomp(x
, y
)) return SCM_BOOL_T
;
2072 scm_floequal(SCM x
, SCM y
)
2081 if (SCM_REALPART(x
) != SCM_REALPART(y
)) return SCM_BOOL_F
;
2082 if (!(SCM_CPLXP(x
) && (SCM_IMAG(x
) != SCM_IMAG(y
)))) return SCM_BOOL_T
;
2090 SCM_PROC(s_number_p
, "number?", 1, 0, 0, scm_number_p
);
2091 SCM_PROC(s_complex_p
, "complex?", 1, 0, 0, scm_number_p
);
2101 if SCM_INUMP(x
) return SCM_BOOL_T
;
2103 if (SCM_NIMP(x
) && SCM_NUMP(x
)) return SCM_BOOL_T
;
2106 if (SCM_NIMP(x
) && SCM_NUMP(x
)) return SCM_BOOL_T
;
2115 SCM_PROC(s_real_p
, "real?", 1, 0, 0, scm_real_p
);
2116 SCM_PROC(s_rational_p
, "rational?", 1, 0, 0, scm_real_p
);
2141 SCM_PROC(s_int_p
, "int?", 1, 0, 0, scm_int_p
);
2152 if SCM_INUMP(x
) return SCM_BOOL_T
;
2153 if SCM_IMP(x
) return SCM_BOOL_F
;
2155 if SCM_BIGP(x
) return SCM_BOOL_T
;
2157 if (!SCM_INEXP(x
)) return SCM_BOOL_F
;
2158 if SCM_CPLXP(x
) return SCM_BOOL_F
;
2159 r
= SCM_REALPART(x
);
2160 if (r
==floor(r
)) return SCM_BOOL_T
;
2166 #endif /* SCM_FLOATS */
2168 SCM_PROC(s_inexact_p
, "inexact?", 1, 0, 0, scm_inexact_p
);
2171 scm_inexact_p(SCM x
)
2179 if (SCM_NIMP(x
) && SCM_INEXP(x
)) return SCM_BOOL_T
;
2187 SCM_PROC1 (s_eq_p
, "=?", scm_tc7_rpsubr
, scm_num_eq_p
);
2190 scm_num_eq_p (SCM x
, SCM y
)
2204 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_eq_p
);
2207 if SCM_INUMP(y
) return SCM_BOOL_F
;
2208 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2209 if SCM_BIGP(y
) return (0==scm_bigcomp(x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2210 SCM_ASRTGO(SCM_INEXP(y
), bady
);
2212 return (SCM_REALP(y
) && (scm_big2dbl(x
)==SCM_REALPART(y
))) ? SCM_BOOL_T
: SCM_BOOL_F
;
2214 SCM_ASRTGO(SCM_INEXP(x
), badx
);
2216 SCM_ASSERT(SCM_NIMP(x
) && SCM_INEXP(x
), x
, SCM_ARG1
, s_eq_p
);
2218 if SCM_INUMP(y
) {t
= x
; x
= y
; y
= t
; goto realint
;}
2220 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2221 if SCM_BIGP(y
) {t
= x
; x
= y
; y
= t
; goto bigreal
;}
2222 SCM_ASRTGO(SCM_INEXP(y
), bady
);
2224 SCM_ASRTGO(SCM_NIMP(y
) && SCM_INEXP(y
), bady
);
2226 if (SCM_REALPART(x
) != SCM_REALPART(y
)) return SCM_BOOL_F
;
2228 return (SCM_CPLXP(y
) && (SCM_IMAG(x
)==SCM_IMAG(y
))) ? SCM_BOOL_T
: SCM_BOOL_F
;
2229 return SCM_CPLXP(y
) ? SCM_BOOL_F
: SCM_BOOL_T
;
2233 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2234 if SCM_BIGP(y
) return SCM_BOOL_F
;
2236 if (!(SCM_INEXP(y
)))
2237 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_eq_p
);
2241 if (!(SCM_NIMP(y
) && SCM_INEXP(y
)))
2242 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_eq_p
);
2246 return (SCM_REALP(y
) && (((double)SCM_INUM(x
))==SCM_REALPART(y
))) ? SCM_BOOL_T
: SCM_BOOL_F
;
2251 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_eq_p
);
2252 if SCM_INUMP(y
) return SCM_BOOL_F
;
2253 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
2254 return (0==scm_bigcomp(x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2258 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
2259 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_eq_p
);
2264 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_eq_p
);
2265 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_eq_p
);
2268 return ((long)x
==(long)y
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2273 SCM_PROC1 (s_less_p
, "<?", scm_tc7_rpsubr
, scm_less_p
);
2276 scm_less_p(SCM x
, SCM y
)
2289 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_less_p
);
2292 if SCM_INUMP(y
) return SCM_BIGSIGN(x
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2293 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2294 if SCM_BIGP(y
) return (1==scm_bigcomp(x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2295 SCM_ASRTGO(SCM_REALP(y
), bady
);
2296 return (scm_big2dbl(x
) < SCM_REALPART(y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2298 SCM_ASRTGO(SCM_REALP(x
), badx
);
2300 SCM_ASSERT(SCM_NIMP(x
) && SCM_REALP(x
), x
, SCM_ARG1
, s_less_p
);
2303 return (SCM_REALPART(x
) < ((double)SCM_INUM(y
))) ? SCM_BOOL_T
: SCM_BOOL_F
;
2305 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2306 if SCM_BIGP(y
) return (SCM_REALPART(x
) < scm_big2dbl(y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2307 SCM_ASRTGO(SCM_REALP(y
), bady
);
2309 SCM_ASRTGO(SCM_NIMP(y
) && SCM_REALP(y
), bady
);
2311 return (SCM_REALPART(x
) < SCM_REALPART(y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2315 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2316 if SCM_BIGP(y
) return SCM_BIGSIGN(y
) ? SCM_BOOL_F
: SCM_BOOL_T
;
2318 if (!(SCM_REALP(y
)))
2319 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_less_p
);
2323 if (!(SCM_NIMP(y
) && SCM_REALP(y
)))
2324 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_less_p
);
2327 return (((double)SCM_INUM(x
)) < SCM_REALPART(y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2332 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_less_p
);
2333 if SCM_INUMP(y
) return SCM_BIGSIGN(x
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2334 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
2335 return (1==scm_bigcomp(x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2339 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
2340 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_less_p
);
2342 return SCM_BIGSIGN(y
) ? SCM_BOOL_F
: SCM_BOOL_T
;
2345 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_less_p
);
2346 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_less_p
);
2349 return ((long)x
< (long)y
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2353 SCM_PROC1 (s_gr_p
, ">?", scm_tc7_rpsubr
, scm_gr_p
);
2356 scm_gr_p(SCM x
, SCM y
)
2364 return scm_less_p(y
, x
);
2369 SCM_PROC1 (s_leq_p
, "<=?", scm_tc7_rpsubr
, scm_leq_p
);
2372 scm_leq_p(SCM x
, SCM y
)
2380 return SCM_BOOL_NOT(scm_less_p(y
, x
));
2385 SCM_PROC1 (s_geq_p
, ">=?", scm_tc7_rpsubr
, scm_geq_p
);
2388 scm_geq_p(SCM x
, SCM y
)
2396 return SCM_BOOL_NOT(scm_less_p(x
, y
));
2401 SCM_PROC(s_zero_p
, "zero?", 1, 0, 0, scm_zero_p
);
2414 SCM_ASRTGO(SCM_NIMP(z
), badz
);
2415 if SCM_BIGP(z
) return SCM_BOOL_F
;
2417 if (!(SCM_INEXP(z
)))
2418 badz
: scm_wta(z
, (char *)SCM_ARG1
, s_zero_p
);
2421 SCM_ASSERT(SCM_NIMP(z
) && SCM_INEXP(z
), z
, SCM_ARG1
, s_zero_p
);
2423 return (z
==scm_flo0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2428 SCM_ASSERT(SCM_NIMP(z
) && SCM_BIGP(z
), z
, SCM_ARG1
, s_zero_p
);
2432 SCM_ASSERT(SCM_INUMP(z
), z
, SCM_ARG1
, s_zero_p
);
2435 return (z
==SCM_INUM0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2440 SCM_PROC(s_positive_p
, "positive?", 1, 0, 0, scm_positive_p
);
2443 scm_positive_p(SCM x
)
2453 SCM_ASRTGO(SCM_NIMP(x
), badx
);
2454 if SCM_BIGP(x
) return SCM_TYP16(x
)==scm_tc16_bigpos
? SCM_BOOL_T
: SCM_BOOL_F
;
2456 if (!(SCM_REALP(x
)))
2457 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_positive_p
);
2460 SCM_ASSERT(SCM_NIMP(x
) && SCM_REALP(x
), x
, SCM_ARG1
, s_positive_p
);
2462 return (SCM_REALPART(x
) > 0.0) ? SCM_BOOL_T
: SCM_BOOL_F
;
2467 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_positive_p
);
2468 return SCM_TYP16(x
)==scm_tc16_bigpos
? SCM_BOOL_T
: SCM_BOOL_F
;
2471 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_positive_p
);
2474 return (x
> SCM_INUM0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2479 SCM_PROC(s_negative_p
, "negative?", 1, 0, 0, scm_negative_p
);
2482 scm_negative_p(SCM x
)
2492 SCM_ASRTGO(SCM_NIMP(x
), badx
);
2493 if SCM_BIGP(x
) return SCM_TYP16(x
)==scm_tc16_bigpos
? SCM_BOOL_F
: SCM_BOOL_T
;
2495 if (!(SCM_REALP(x
)))
2496 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_negative_p
);
2499 SCM_ASSERT(SCM_NIMP(x
) && SCM_REALP(x
), x
, SCM_ARG1
, s_negative_p
);
2501 return (SCM_REALPART(x
) < 0.0) ? SCM_BOOL_T
: SCM_BOOL_F
;
2506 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_negative_p
);
2507 return (SCM_TYP16(x
)==scm_tc16_bigneg
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2510 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_negative_p
);
2513 return (x
< SCM_INUM0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2517 SCM_PROC1 (s_max
, "max", scm_tc7_asubr
, scm_max
);
2520 scm_max(SCM x
, SCM y
)
2533 if (!(SCM_NUMBERP(x
)))
2534 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_max
);
2541 SCM_ASRTGO(SCM_NIMP(x
), badx
);
2543 if SCM_INUMP(y
) return SCM_BIGSIGN(x
) ? y
: x
;
2544 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2545 if SCM_BIGP(y
) return (1==scm_bigcomp(x
, y
)) ? y
: x
;
2546 SCM_ASRTGO(SCM_REALP(y
), bady
);
2548 return (z
< SCM_REALPART(y
)) ? y
: scm_makdbl(z
, 0.0);
2550 SCM_ASRTGO(SCM_REALP(x
), badx
);
2552 SCM_ASSERT(SCM_NIMP(x
) && SCM_REALP(x
), x
, SCM_ARG1
, s_max
);
2555 return (SCM_REALPART(x
) < (z
= SCM_INUM(y
))) ? scm_makdbl(z
, 0.0) : x
;
2557 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2559 return (SCM_REALPART(x
) < (z
= scm_big2dbl(y
))) ? scm_makdbl(z
, 0.0) : x
;
2560 SCM_ASRTGO(SCM_REALP(y
), bady
);
2562 SCM_ASRTGO(SCM_NIMP(y
) && SCM_REALP(y
), bady
);
2564 return (SCM_REALPART(x
) < SCM_REALPART(y
)) ? y
: x
;
2568 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2569 if SCM_BIGP(y
) return SCM_BIGSIGN(y
) ? x
: y
;
2571 if (!(SCM_REALP(y
)))
2572 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_max
);
2576 if (!(SCM_NIMP(y
) && SCM_REALP(y
)))
2577 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_max
);
2580 return ((z
= SCM_INUM(x
)) < SCM_REALPART(y
)) ? y
: scm_makdbl(z
, 0.0);
2585 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_max
);
2586 if SCM_INUMP(y
) return SCM_BIGSIGN(x
) ? y
: x
;
2587 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
2588 return (1==scm_bigcomp(x
, y
)) ? y
: x
;
2592 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
2593 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_max
);
2595 return SCM_BIGSIGN(y
) ? x
: y
;
2598 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_max
);
2599 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_max
);
2602 return ((long)x
< (long)y
) ? y
: x
;
2608 SCM_PROC1 (s_min
, "min", scm_tc7_asubr
, scm_min
);
2611 scm_min(SCM x
, SCM y
)
2624 if (!(SCM_NUMBERP(x
)))
2625 badx
:scm_wta(x
, (char *)SCM_ARG1
, s_min
);
2632 SCM_ASRTGO(SCM_NIMP(x
), badx
);
2634 if SCM_INUMP(y
) return SCM_BIGSIGN(x
) ? x
: y
;
2635 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2636 if SCM_BIGP(y
) return (-1==scm_bigcomp(x
, y
)) ? y
: x
;
2637 SCM_ASRTGO(SCM_REALP(y
), bady
);
2639 return (z
> SCM_REALPART(y
)) ? y
: scm_makdbl(z
, 0.0);
2641 SCM_ASRTGO(SCM_REALP(x
), badx
);
2643 SCM_ASSERT(SCM_NIMP(x
) && SCM_REALP(x
), x
, SCM_ARG1
, s_min
);
2645 if SCM_INUMP(y
) return (SCM_REALPART(x
) > (z
= SCM_INUM(y
))) ? scm_makdbl(z
, 0.0) : x
;
2647 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2648 if SCM_BIGP(y
) return (SCM_REALPART(x
) > (z
= scm_big2dbl(y
))) ? scm_makdbl(z
, 0.0) : x
;
2649 SCM_ASRTGO(SCM_REALP(y
), bady
);
2651 SCM_ASRTGO(SCM_NIMP(y
) && SCM_REALP(y
), bady
);
2653 return (SCM_REALPART(x
) > SCM_REALPART(y
)) ? y
: x
;
2657 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2658 if SCM_BIGP(y
) return SCM_BIGSIGN(y
) ? y
: x
;
2660 if (!(SCM_REALP(y
)))
2661 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_min
);
2665 if (!(SCM_NIMP(y
) && SCM_REALP(y
)))
2666 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_min
);
2669 return ((z
= SCM_INUM(x
)) > SCM_REALPART(y
)) ? y
: scm_makdbl(z
, 0.0);
2674 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_min
);
2675 if SCM_INUMP(y
) return SCM_BIGSIGN(x
) ? x
: y
;
2676 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
2677 return (-1==scm_bigcomp(x
, y
)) ? y
: x
;
2681 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
2682 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_min
);
2684 return SCM_BIGSIGN(y
) ? y
: x
;
2687 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_min
);
2688 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_min
);
2691 return ((long)x
> (long)y
) ? y
: x
;
2697 SCM_PROC1 (s_sum
, "+", scm_tc7_asubr
, scm_sum
);
2700 scm_sum(SCM x
, SCM y
)
2709 if SCM_UNBNDP(x
) return SCM_INUM0
;
2711 if (!(SCM_NUMBERP(x
)))
2712 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_sum
);
2720 SCM_ASRTGO(SCM_NIMP(x
), badx
);
2722 if SCM_INUMP(y
) {t
= x
; x
= y
; y
= t
; goto intbig
;}
2723 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2725 if (SCM_NUMDIGS(x
) > SCM_NUMDIGS(y
)) {t
= x
; x
= y
; y
= t
;}
2726 return scm_addbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BIGSIGN(x
), y
, 0);
2728 SCM_ASRTGO(SCM_INEXP(y
), bady
);
2729 bigreal
: return scm_makdbl(scm_big2dbl(x
)+SCM_REALPART(y
), SCM_CPLXP(y
)?SCM_IMAG(y
):0.0);
2731 SCM_ASRTGO(SCM_INEXP(x
), badx
);
2733 SCM_ASRTGO(SCM_NIMP(x
) && SCM_INEXP(x
), badx
);
2735 if SCM_INUMP(y
) {t
= x
; x
= y
; y
= t
; goto intreal
;}
2737 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2738 if SCM_BIGP(y
) {t
= x
; x
= y
; y
= t
; goto bigreal
;}
2740 else if (!(SCM_INEXP(y
)))
2741 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_sum
);
2745 if (!(SCM_NIMP(y
) && SCM_INEXP(y
)))
2746 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_sum
);
2750 if SCM_CPLXP(x
) i
= SCM_IMAG(x
);
2751 if SCM_CPLXP(y
) i
+= SCM_IMAG(y
);
2752 return scm_makdbl(SCM_REALPART(x
)+SCM_REALPART(y
), i
); }
2756 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2759 # ifndef SCM_DIGSTOOBIG
2760 long z
= scm_pseudolong(SCM_INUM(x
));
2761 return scm_addbig((SCM_BIGDIG
*)&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
2763 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
2764 scm_longdigs(SCM_INUM(x
), zdigs
);
2765 return scm_addbig(zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
2768 SCM_ASRTGO(SCM_INEXP(y
), bady
);
2770 SCM_ASRTGO(SCM_NIMP(y
) && SCM_INEXP(y
), bady
);
2772 intreal
: return scm_makdbl(SCM_INUM(x
)+SCM_REALPART(y
), SCM_CPLXP(y
)?SCM_IMAG(y
):0.0);
2778 SCM_ASRTGO(SCM_NIMP(x
) && SCM_BIGP(x
), badx
);
2779 if SCM_INUMP(y
) {t
= x
; x
= y
; y
= t
; goto intbig
;}
2780 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
2781 if (SCM_NUMDIGS(x
) > SCM_NUMDIGS(y
)) {t
= x
; x
= y
; y
= t
;}
2782 return scm_addbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BIGSIGN(x
), y
, 0);
2786 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
2787 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_sum
);
2790 # ifndef SCM_DIGSTOOBIG
2791 long z
= scm_pseudolong(SCM_INUM(x
));
2792 return scm_addbig(&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
2794 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
2795 scm_longdigs(SCM_INUM(x
), zdigs
);
2796 return scm_addbig(zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
2801 SCM_ASRTGO(SCM_INUMP(x
), badx
);
2802 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_sum
);
2805 x
= SCM_INUM(x
)+SCM_INUM(y
);
2806 if SCM_FIXABLE(x
) return SCM_MAKINUM(x
);
2808 return scm_long2big(x
);
2811 return scm_makdbl((double)x
, 0.0);
2813 scm_num_overflow (s_sum
);
2814 return SCM_UNSPECIFIED
;
2822 SCM_PROC1 (s_difference
, "-", scm_tc7_asubr
, scm_difference
);
2825 scm_difference(SCM x
, SCM y
)
2828 scm_difference(x
, y
)
2837 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_difference
);
2842 x
= scm_copybig(x
, !SCM_BIGSIGN(x
));
2843 return SCM_NUMDIGS(x
) * SCM_BITSPERDIG
/SCM_CHAR_BIT
<= sizeof(SCM
) ?
2844 scm_big2inum(x
, SCM_NUMDIGS(x
)) : x
;
2847 SCM_ASRTGO(SCM_INEXP(x
), badx
);
2848 return scm_makdbl(-SCM_REALPART(x
), SCM_CPLXP(x
)?-SCM_IMAG(x
):0.0);
2850 if SCM_INUMP(y
) return scm_sum(x
, SCM_MAKINUM(-SCM_INUM(y
)));
2852 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2854 if SCM_BIGP(y
) return (SCM_NUMDIGS(x
) < SCM_NUMDIGS(y
)) ?
2855 scm_addbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BIGSIGN(x
), y
, 0x0100) :
2856 scm_addbig(SCM_BDIGITS(y
), SCM_NUMDIGS(y
), SCM_BIGSIGN(y
) ^ 0x0100, x
, 0);
2857 SCM_ASRTGO(SCM_INEXP(y
), bady
);
2858 return scm_makdbl(scm_big2dbl(x
)-SCM_REALPART(y
), SCM_CPLXP(y
)?-SCM_IMAG(y
):0.0);
2860 SCM_ASRTGO(SCM_INEXP(x
), badx
);
2861 if SCM_BIGP(y
) return scm_makdbl(SCM_REALPART(x
)-scm_big2dbl(y
), SCM_CPLXP(x
)?SCM_IMAG(x
):0.0);
2862 SCM_ASRTGO(SCM_INEXP(y
), bady
);
2864 SCM_ASRTGO(SCM_INEXP(x
), badx
);
2865 SCM_ASRTGO(SCM_NIMP(y
) && SCM_INEXP(y
), bady
);
2869 return scm_makdbl(SCM_REAL(x
)-SCM_REAL(y
), SCM_IMAG(x
)-SCM_IMAG(y
));
2871 return scm_makdbl(SCM_REAL(x
)-SCM_REALPART(y
), SCM_IMAG(x
));
2872 return scm_makdbl(SCM_REALPART(x
)-SCM_REALPART(y
), SCM_CPLXP(y
)?-SCM_IMAG(y
):0.0);
2874 if SCM_UNBNDP(y
) {x
= -SCM_INUM(x
); goto checkx
;}
2877 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2879 # ifndef SCM_DIGSTOOBIG
2880 long z
= scm_pseudolong(SCM_INUM(x
));
2881 return scm_addbig((SCM_BIGDIG
*)&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0x0100);
2883 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
2884 scm_longdigs(SCM_INUM(x
), zdigs
);
2885 return scm_addbig(zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0x0100);
2889 if (!(SCM_INEXP(y
)))
2890 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_difference
);
2894 if (!(SCM_NIMP(y
) && SCM_INEXP(y
)))
2895 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_difference
);
2898 return scm_makdbl(SCM_INUM(x
)-SCM_REALPART(y
), SCM_CPLXP(y
)?-SCM_IMAG(y
):0.0);
2903 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_difference
);
2905 x
= scm_copybig(x
, !SCM_BIGSIGN(x
));
2906 return SCM_NUMDIGS(x
) * SCM_BITSPERDIG
/SCM_CHAR_BIT
<= sizeof(SCM
) ?
2907 scm_big2inum(x
, SCM_NUMDIGS(x
)) : x
;
2910 # ifndef SCM_DIGSTOOBIG
2911 long z
= scm_pseudolong(SCM_INUM(y
));
2912 return scm_addbig(&z
, SCM_DIGSPERLONG
, (y
< 0) ? 0 : 0x0100, x
, 0);
2914 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
2915 scm_longdigs(SCM_INUM(x
), zdigs
);
2916 return scm_addbig(zdigs
, SCM_DIGSPERLONG
, (y
< 0) ? 0 : 0x0100, x
, 0);
2919 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
2920 return (SCM_NUMDIGS(x
) < SCM_NUMDIGS(y
)) ?
2921 scm_addbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BIGSIGN(x
), y
, 0x0100) :
2922 scm_addbig(SCM_BDIGITS(y
), SCM_NUMDIGS(y
), SCM_BIGSIGN(y
) ^ 0x0100, x
, 0);
2924 if SCM_UNBNDP(y
) {x
= -SCM_INUM(x
); goto checkx
;}
2927 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
2928 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_difference
);
2931 # ifndef SCM_DIGSTOOBIG
2932 long z
= scm_pseudolong(SCM_INUM(x
));
2933 return scm_addbig(&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0x0100);
2935 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
2936 scm_longdigs(SCM_INUM(x
), zdigs
);
2937 return scm_addbig(zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0x0100);
2942 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_difference
);
2943 if SCM_UNBNDP(y
) {x
= -SCM_INUM(x
); goto checkx
;}
2944 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_difference
);
2947 x
= SCM_INUM(x
)-SCM_INUM(y
);
2949 if SCM_FIXABLE(x
) return SCM_MAKINUM(x
);
2951 return scm_long2big(x
);
2954 return scm_makdbl((double)x
, 0.0);
2956 scm_num_overflow (s_difference
);
2957 return SCM_UNSPECIFIED
;
2965 SCM_PROC1 (s_product
, "*", scm_tc7_asubr
, scm_product
);
2968 scm_product(SCM x
, SCM y
)
2977 if SCM_UNBNDP(x
) return SCM_MAKINUM(1L);
2979 if (!(SCM_NUMBERP(x
)))
2980 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_product
);
2988 SCM_ASRTGO(SCM_NIMP(x
), badx
);
2990 if SCM_INUMP(y
) {t
= x
; x
= y
; y
= t
; goto intbig
;}
2991 SCM_ASRTGO(SCM_NIMP(y
), bady
);
2992 if SCM_BIGP(y
) return scm_mulbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
2993 SCM_BIGSIGN(x
) ^ SCM_BIGSIGN(y
));
2994 SCM_ASRTGO(SCM_INEXP(y
), bady
);
2996 double bg
= scm_big2dbl(x
);
2997 return scm_makdbl(bg
*SCM_REALPART(y
), SCM_CPLXP(y
)?bg
*SCM_IMAG(y
):0.0); }
2999 SCM_ASRTGO(SCM_INEXP(x
), badx
);
3001 SCM_ASRTGO(SCM_NIMP(x
) && SCM_INEXP(x
), badx
);
3003 if SCM_INUMP(y
) {t
= x
; x
= y
; y
= t
; goto intreal
;}
3005 SCM_ASRTGO(SCM_NIMP(y
), bady
);
3006 if SCM_BIGP(y
) {t
= x
; x
= y
; y
= t
; goto bigreal
;}
3008 else if (!(SCM_INEXP(y
)))
3009 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_product
);
3013 if (!(SCM_NIMP(y
) && SCM_INEXP(y
)))
3014 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_product
);
3019 return scm_makdbl(SCM_REAL(x
)*SCM_REAL(y
)-SCM_IMAG(x
)*SCM_IMAG(y
),
3020 SCM_REAL(x
)*SCM_IMAG(y
)+SCM_IMAG(x
)*SCM_REAL(y
));
3022 return scm_makdbl(SCM_REAL(x
)*SCM_REALPART(y
), SCM_IMAG(x
)*SCM_REALPART(y
));
3023 return scm_makdbl(SCM_REALPART(x
)*SCM_REALPART(y
),
3024 SCM_CPLXP(y
)?SCM_REALPART(x
)*SCM_IMAG(y
):0.0);
3028 SCM_ASRTGO(SCM_NIMP(y
), bady
);
3030 intbig
: if (SCM_INUM0
==x
) return x
; if (SCM_MAKINUM(1L)==x
) return y
;
3032 # ifndef SCM_DIGSTOOBIG
3033 long z
= scm_pseudolong(SCM_INUM(x
));
3034 return scm_mulbig((SCM_BIGDIG
*)&z
, SCM_DIGSPERLONG
, SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
3035 SCM_BIGSIGN(y
) ? (x
>0) : (x
<0));
3037 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3038 scm_longdigs(SCM_INUM(x
), zdigs
);
3039 return scm_mulbig(zdigs
, SCM_DIGSPERLONG
, SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
3040 SCM_BIGSIGN(y
) ? (x
>0) : (x
<0));
3044 SCM_ASRTGO(SCM_INEXP(y
), bady
);
3046 SCM_ASRTGO(SCM_NIMP(y
) && SCM_INEXP(y
), bady
);
3048 intreal
: return scm_makdbl(SCM_INUM(x
)*SCM_REALPART(y
), SCM_CPLXP(y
)?SCM_INUM(x
)*SCM_IMAG(y
):0.0);
3053 SCM_ASRTGO(SCM_NIMP(x
) && SCM_BIGP(x
), badx
);
3054 if SCM_INUMP(y
) {SCM t
= x
; x
= y
; y
= t
; goto intbig
;}
3055 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
3056 return scm_mulbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
3057 SCM_BIGSIGN(x
) ^ SCM_BIGSIGN(y
));
3061 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
3062 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_product
);
3064 intbig
: if (SCM_INUM0
==x
) return x
; if (SCM_MAKINUM(1L)==x
) return y
;
3066 # ifndef SCM_DIGSTOOBIG
3067 long z
= scm_pseudolong(SCM_INUM(x
));
3068 return scm_mulbig(&z
, SCM_DIGSPERLONG
, SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
3069 SCM_BIGSIGN(y
) ? (x
>0) : (x
<0));
3071 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3072 scm_longdigs(SCM_INUM(x
), zdigs
);
3073 return scm_mulbig(zdigs
, SCM_DIGSPERLONG
, SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
3074 SCM_BIGSIGN(y
) ? (x
>0) : (x
<0));
3079 SCM_ASRTGO(SCM_INUMP(x
), badx
);
3080 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_product
);
3090 if (k
!= SCM_INUM(y
) || k
/i
!= j
)
3092 { int sgn
= (i
< 0) ^ (j
< 0);
3093 # ifndef SCM_DIGSTOOBIG
3094 i
= scm_pseudolong(i
);
3095 j
= scm_pseudolong(j
);
3096 return scm_mulbig((SCM_BIGDIG
*)&i
, SCM_DIGSPERLONG
,
3097 (SCM_BIGDIG
*)&j
, SCM_DIGSPERLONG
, sgn
);
3098 # else /* SCM_DIGSTOOBIG */
3099 SCM_BIGDIG idigs
[SCM_DIGSPERLONG
];
3100 SCM_BIGDIG jdigs
[SCM_DIGSPERLONG
];
3101 scm_longdigs(i
, idigs
);
3102 scm_longdigs(j
, jdigs
);
3103 return scm_mulbig(idigs
, SCM_DIGSPERLONG
, jdigs
, SCM_DIGSPERLONG
, sgn
);
3108 return scm_makdbl(((double)i
)*((double)j
), 0.0);
3110 scm_num_overflow (s_product
);
3120 scm_num2dbl (SCM a
, char * why
)
3123 scm_num2dbl (a
, why
)
3129 return (double) SCM_INUM (a
);
3131 SCM_ASSERT (SCM_NIMP (a
), a
, "wrong type argument", why
);
3133 return (SCM_REALPART (a
));
3136 return scm_big2dbl (a
);
3138 SCM_ASSERT (0, a
, "wrong type argument", why
);
3139 return SCM_UNSPECIFIED
;
3143 SCM_PROC(s_fuck
, "fuck", 1, 0, 0, scm_fuck
);
3153 return scm_makdbl (scm_num2dbl (a
, "just because"), 0.0);
3156 SCM_PROC1 (s_divide
, "/", scm_tc7_asubr
, scm_divide
);
3159 scm_divide(SCM x
, SCM y
)
3172 badx
: scm_wta(x
, (char *)SCM_ARG1
, s_divide
);
3176 if SCM_BIGP(x
) return scm_makdbl(1.0/scm_big2dbl(x
), 0.0);
3178 SCM_ASRTGO(SCM_INEXP(x
), badx
);
3179 if SCM_REALP(x
) return scm_makdbl(1.0/SCM_REALPART(x
), 0.0);
3180 r
= SCM_REAL(x
); i
= SCM_IMAG(x
); d
= r
*r
+i
*i
;
3181 return scm_makdbl(r
/d
, -i
/d
);
3190 scm_num_overflow (s_divide
);
3194 if (z
< SCM_BIGRAD
) {
3195 SCM w
= scm_copybig(x
, SCM_BIGSIGN(x
) ? (y
>0) : (y
<0));
3196 return scm_divbigdig(SCM_BDIGITS(w
), SCM_NUMDIGS(w
), (SCM_BIGDIG
)z
) ?
3197 scm_makdbl(scm_big2dbl(x
)/SCM_INUM(y
), 0.0) : scm_normbig(w
);
3199 # ifndef SCM_DIGSTOOBIG
3200 z
= scm_pseudolong(z
);
3201 z
= scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), (SCM_BIGDIG
*)&z
, SCM_DIGSPERLONG
,
3202 SCM_BIGSIGN(x
) ? (y
>0) : (y
<0), 3);
3204 { SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3205 scm_longdigs(z
, zdigs
);
3206 z
= scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), zdigs
, SCM_DIGSPERLONG
,
3207 SCM_BIGSIGN(x
) ? (y
>0) : (y
<0), 3);}
3209 return z
? z
: scm_makdbl(scm_big2dbl(x
)/SCM_INUM(y
), 0.0);
3211 SCM_ASRTGO(SCM_NIMP(y
), bady
);
3213 z
= scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
3214 SCM_BIGSIGN(x
) ^ SCM_BIGSIGN(y
), 3);
3215 return z
? z
: scm_makdbl(scm_big2dbl(x
)/scm_big2dbl(y
), 0.0);
3217 SCM_ASRTGO(SCM_INEXP(y
), bady
);
3218 if SCM_REALP(y
) return scm_makdbl(scm_big2dbl(x
)/SCM_REALPART(y
), 0.0);
3223 SCM_ASRTGO(SCM_INEXP(x
), badx
);
3224 if SCM_INUMP(y
) {d
= SCM_INUM(y
); goto basic_div
;}
3226 SCM_ASRTGO(SCM_NIMP(y
), bady
);
3227 if SCM_BIGP(y
) {d
= scm_big2dbl(y
); goto basic_div
;}
3228 SCM_ASRTGO(SCM_INEXP(y
), bady
);
3230 SCM_ASRTGO(SCM_NIMP(y
) && SCM_INEXP(y
), bady
);
3233 d
= SCM_REALPART(y
);
3234 basic_div
: return scm_makdbl(SCM_REALPART(x
)/d
, SCM_CPLXP(x
)?SCM_IMAG(x
)/d
:0.0);
3236 a
= SCM_REALPART(x
);
3237 if SCM_REALP(x
) goto complex_div
;
3238 r
= SCM_REAL(y
); i
= SCM_IMAG(y
); d
= r
*r
+i
*i
;
3239 return scm_makdbl((a
*r
+SCM_IMAG(x
)*i
)/d
, (SCM_IMAG(x
)*r
-a
*i
)/d
);
3242 if ((SCM_MAKINUM(1L)==x
) || (SCM_MAKINUM(-1L)==x
)) return x
;
3243 return scm_makdbl(1.0/((double)SCM_INUM(x
)), 0.0);
3247 SCM_ASRTGO(SCM_NIMP(y
), bady
);
3248 if SCM_BIGP(y
) return scm_makdbl(SCM_INUM(x
)/scm_big2dbl(y
), 0.0);
3250 if (!(SCM_INEXP(y
)))
3251 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_divide
);
3255 if (!(SCM_NIMP(y
) && SCM_INEXP(y
)))
3256 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_divide
);
3260 return scm_makdbl(SCM_INUM(x
)/SCM_REALPART(y
), 0.0);
3263 r
= SCM_REAL(y
); i
= SCM_IMAG(y
); d
= r
*r
+i
*i
;
3264 return scm_makdbl((a
*r
)/d
, (-a
*i
)/d
);
3270 SCM_ASSERT(SCM_NIMP(x
) && SCM_BIGP(x
), x
, SCM_ARG1
, s_divide
);
3271 if SCM_UNBNDP(y
) goto ov
;
3277 if (z
< SCM_BIGRAD
) {
3278 SCM w
= scm_copybig(x
, SCM_BIGSIGN(x
) ? (y
>0) : (y
<0));
3279 if (scm_divbigdig(SCM_BDIGITS(w
), SCM_NUMDIGS(w
), (SCM_BIGDIG
)z
)) goto ov
;
3282 # ifndef SCM_DIGSTOOBIG
3283 z
= scm_pseudolong(z
);
3284 z
= scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), &z
, SCM_DIGSPERLONG
,
3285 SCM_BIGSIGN(x
) ? (y
>0) : (y
<0), 3);
3287 { SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3288 scm_longdigs(z
, zdigs
);
3289 z
= scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), zdigs
, SCM_DIGSPERLONG
,
3290 SCM_BIGSIGN(x
) ? (y
>0) : (y
<0), 3);}
3293 SCM_ASRTGO(SCM_NIMP(y
) && SCM_BIGP(y
), bady
);
3294 z
= scm_divbigbig(SCM_BDIGITS(x
), SCM_NUMDIGS(x
), SCM_BDIGITS(y
), SCM_NUMDIGS(y
),
3295 SCM_BIGSIGN(x
) ^ SCM_BIGSIGN(y
), 3);
3301 if ((SCM_MAKINUM(1L)==x
) || (SCM_MAKINUM(-1L)==x
)) return x
;
3306 if (!(SCM_NIMP(y
) && SCM_BIGP(y
)))
3307 bady
: scm_wta(y
, (char *)SCM_ARG2
, s_divide
);
3312 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_divide
);
3314 if ((SCM_MAKINUM(1L)==x
) || (SCM_MAKINUM(-1L)==x
)) return x
;
3317 SCM_ASSERT(SCM_INUMP(y
), y
, SCM_ARG2
, s_divide
);
3321 long z
= SCM_INUM(y
);
3322 if ((0==z
) || SCM_INUM(x
)%z
) goto ov
;
3324 if SCM_FIXABLE(z
) return SCM_MAKINUM(z
);
3326 return scm_long2big(z
);
3329 ov
: return scm_makdbl(((double)SCM_INUM(x
))/((double)SCM_INUM(y
)), 0.0);
3331 ov
: scm_num_overflow (s_divide
);
3332 return SCM_UNSPECIFIED
;
3341 SCM_PROC1 (s_asinh
, "$asinh", scm_tc7_cxr
, (SCM (*)()) scm_asinh
);
3351 return log(x
+sqrt(x
*x
+1));
3357 SCM_PROC1 (s_acosh
, "$acosh", scm_tc7_cxr
, (SCM (*)()) scm_acosh
);
3367 return log(x
+sqrt(x
*x
-1));
3373 SCM_PROC1 (s_atanh
, "$atanh", scm_tc7_cxr
, (SCM (*)()) scm_atanh
);
3383 return 0.5*log((1+x
)/(1-x
));
3389 SCM_PROC1 (s_truncate
, "truncate", scm_tc7_cxr
, (SCM (*)()) scm_truncate
);
3392 scm_truncate(double x
)
3399 if (x
< 0.0) return -floor(-x
);
3405 SCM_PROC1 (s_round
, "round", scm_tc7_cxr
, (SCM (*)()) scm_round
);
3415 double plus_half
= x
+ 0.5;
3416 double result
= floor(plus_half
);
3417 /* Adjust so that the scm_round is towards even. */
3418 return (plus_half
== result
&& plus_half
/ 2 != floor(plus_half
/ 2))
3419 ? result
- 1 : result
;
3424 SCM_PROC1 (s_exact_to_inexact
, "exact->inexact", scm_tc7_cxr
, (SCM (*)()) scm_exact_to_inexact
);
3427 scm_exact_to_inexact(double z
)
3430 scm_exact_to_inexact(z
)
3438 SCM_PROC1 (s_i_floor
, "floor", scm_tc7_cxr
, (SCM (*)()) floor
);
3439 SCM_PROC1 (s_i_ceil
, "ceiling", scm_tc7_cxr
, (SCM (*)()) ceil
);
3440 SCM_PROC1 (s_i_sqrt
, "$sqrt", scm_tc7_cxr
, (SCM (*)())sqrt
);
3441 SCM_PROC1 (s_i_abs
, "$abs", scm_tc7_cxr
, (SCM (*)())fabs
);
3442 SCM_PROC1 (s_i_exp
, "$exp", scm_tc7_cxr
, (SCM (*)())exp
);
3443 SCM_PROC1 (s_i_log
, "$log", scm_tc7_cxr
, (SCM (*)())log
);
3444 SCM_PROC1 (s_i_sin
, "$sin", scm_tc7_cxr
, (SCM (*)())sin
);
3445 SCM_PROC1 (s_i_cos
, "$cos", scm_tc7_cxr
, (SCM (*)())cos
);
3446 SCM_PROC1 (s_i_tan
, "$tan", scm_tc7_cxr
, (SCM (*)())tan
);
3447 SCM_PROC1 (s_i_asin
, "$asin", scm_tc7_cxr
, (SCM (*)())asin
);
3448 SCM_PROC1 (s_i_acos
, "$acos", scm_tc7_cxr
, (SCM (*)())acos
);
3449 SCM_PROC1 (s_i_atan
, "$atan", scm_tc7_cxr
, (SCM (*)())atan
);
3450 SCM_PROC1 (s_i_sinh
, "$sinh", scm_tc7_cxr
, (SCM (*)())sinh
);
3451 SCM_PROC1 (s_i_cosh
, "$cosh", scm_tc7_cxr
, (SCM (*)())cosh
);
3452 SCM_PROC1 (s_i_tanh
, "$tanh", scm_tc7_cxr
, (SCM (*)())tanh
);
3454 struct dpair
{double x
, y
;};
3457 scm_two_doubles(z1
, z2
, sstring
, xy
)
3462 if SCM_INUMP(z1
) xy
->x
= SCM_INUM(z1
);
3465 SCM_ASRTGO(SCM_NIMP(z1
), badz1
);
3466 if SCM_BIGP(z1
) xy
->x
= scm_big2dbl(z1
);
3469 if (!(SCM_REALP(z1
)))
3470 badz1
: scm_wta(z1
, (char *)SCM_ARG1
, sstring
);
3472 xy
->x
= SCM_REALPART(z1
);}
3474 {SCM_ASSERT(SCM_NIMP(z1
) && SCM_REALP(z1
), z1
, SCM_ARG1
, sstring
);
3475 xy
->x
= SCM_REALPART(z1
);}
3478 if SCM_INUMP(z2
) xy
->y
= SCM_INUM(z2
);
3481 SCM_ASRTGO(SCM_NIMP(z2
), badz2
);
3482 if SCM_BIGP(z2
) xy
->y
= scm_big2dbl(z2
);
3485 if (!(SCM_REALP(z2
)))
3486 badz2
: scm_wta(z2
, (char *)SCM_ARG2
, sstring
);
3488 xy
->y
= SCM_REALPART(z2
);}
3490 {SCM_ASSERT(SCM_NIMP(z2
) && SCM_REALP(z2
), z2
, SCM_ARG2
, sstring
);
3491 xy
->y
= SCM_REALPART(z2
);}
3499 SCM_PROC(s_sys_expt
, "$expt", 2, 0, 0, scm_sys_expt
);
3502 scm_sys_expt(SCM z1
, SCM z2
)
3505 scm_sys_expt(z1
, z2
)
3511 scm_two_doubles(z1
, z2
, s_sys_expt
, &xy
);
3512 return scm_makdbl(pow(xy
.x
, xy
.y
), 0.0);
3517 SCM_PROC(s_sys_atan2
, "$atan2", 2, 0, 0, scm_sys_atan2
);
3520 scm_sys_atan2(SCM z1
, SCM z2
)
3523 scm_sys_atan2(z1
, z2
)
3529 scm_two_doubles(z1
, z2
, s_sys_atan2
, &xy
);
3530 return scm_makdbl(atan2(xy
.x
, xy
.y
), 0.0);
3535 SCM_PROC(s_make_rectangular
, "make-rectangular", 2, 0, 0, scm_make_rectangular
);
3538 scm_make_rectangular(SCM z1
, SCM z2
)
3541 scm_make_rectangular(z1
, z2
)
3547 scm_two_doubles(z1
, z2
, s_make_rectangular
, &xy
);
3548 return scm_makdbl(xy
.x
, xy
.y
);
3553 SCM_PROC(s_make_polar
, "make-polar", 2, 0, 0, scm_make_polar
);
3556 scm_make_polar(SCM z1
, SCM z2
)
3559 scm_make_polar(z1
, z2
)
3565 scm_two_doubles(z1
, z2
, s_make_polar
, &xy
);
3566 return scm_makdbl(xy
.x
*cos(xy
.y
), xy
.x
*sin(xy
.y
));
3572 SCM_PROC(s_real_part
, "real-part", 1, 0, 0, scm_real_part
);
3575 scm_real_part(SCM z
)
3584 SCM_ASRTGO(SCM_NIMP(z
), badz
);
3585 if SCM_BIGP(z
) return z
;
3587 if (!(SCM_INEXP(z
)))
3588 badz
: scm_wta(z
, (char *)SCM_ARG1
, s_real_part
);
3591 SCM_ASSERT(SCM_NIMP(z
) && SCM_INEXP(z
), z
, SCM_ARG1
, s_real_part
);
3593 if SCM_CPLXP(z
) return scm_makdbl(SCM_REAL(z
), 0.0);
3600 SCM_PROC(s_imag_part
, "imag-part", 1, 0, 0, scm_imag_part
);
3603 scm_imag_part(SCM z
)
3610 if SCM_INUMP(z
) return SCM_INUM0
;
3612 SCM_ASRTGO(SCM_NIMP(z
), badz
);
3613 if SCM_BIGP(z
) return SCM_INUM0
;
3615 if (!(SCM_INEXP(z
)))
3616 badz
: scm_wta(z
, (char *)SCM_ARG1
, s_imag_part
);
3619 SCM_ASSERT(SCM_NIMP(z
) && SCM_INEXP(z
), z
, SCM_ARG1
, s_imag_part
);
3621 if SCM_CPLXP(z
) return scm_makdbl(SCM_IMAG(z
), 0.0);
3627 SCM_PROC(s_magnitude
, "magnitude", 1, 0, 0, scm_magnitude
);
3630 scm_magnitude(SCM z
)
3637 if SCM_INUMP(z
) return scm_abs(z
);
3639 SCM_ASRTGO(SCM_NIMP(z
), badz
);
3640 if SCM_BIGP(z
) return scm_abs(z
);
3642 if (!(SCM_INEXP(z
)))
3643 badz
: scm_wta(z
, (char *)SCM_ARG1
, s_magnitude
);
3646 SCM_ASSERT(SCM_NIMP(z
) && SCM_INEXP(z
), z
, SCM_ARG1
, s_magnitude
);
3650 double i
= SCM_IMAG(z
), r
= SCM_REAL(z
);
3651 return scm_makdbl(sqrt(i
*i
+r
*r
), 0.0);
3653 return scm_makdbl(fabs(SCM_REALPART(z
)), 0.0);
3659 SCM_PROC(s_angle
, "angle", 1, 0, 0, scm_angle
);
3670 if SCM_INUMP(z
) {x
= (z
>=SCM_INUM0
) ? 1.0 : -1.0; goto do_angle
;}
3672 SCM_ASRTGO(SCM_NIMP(z
), badz
);
3673 if SCM_BIGP(z
) {x
= (SCM_TYP16(z
)==scm_tc16_bigpos
) ? 1.0 : -1.0; goto do_angle
;}
3675 if (!(SCM_INEXP(z
))) {
3676 badz
: scm_wta(z
, (char *)SCM_ARG1
, s_angle
);}
3679 SCM_ASSERT(SCM_NIMP(z
) && SCM_INEXP(z
), z
, SCM_ARG1
, s_angle
);
3683 x
= SCM_REALPART(z
);
3686 x
= SCM_REAL(z
); y
= SCM_IMAG(z
);
3688 return scm_makdbl(atan2(y
, x
), 0.0);
3692 SCM_PROC(s_inexact_to_exact
, "inexact->exact", 1, 0, 0, scm_inexact_to_exact
);
3695 scm_inexact_to_exact(SCM z
)
3698 scm_inexact_to_exact(z
)
3702 if SCM_INUMP(z
) return z
;
3704 SCM_ASRTGO(SCM_NIMP(z
), badz
);
3705 if SCM_BIGP(z
) return z
;
3707 if (!(SCM_REALP(z
)))
3708 badz
: scm_wta(z
, (char *)SCM_ARG1
, s_inexact_to_exact
);
3711 SCM_ASSERT(SCM_NIMP(z
) && SCM_REALP(z
), z
, SCM_ARG1
, s_inexact_to_exact
);
3715 double u
= floor(SCM_REALPART(z
)+0.5);
3716 if ((u
<= SCM_MOST_POSITIVE_FIXNUM
) && (-u
<= -SCM_MOST_NEGATIVE_FIXNUM
)) {
3717 /* Negation is a workaround for HP700 cc bug */
3718 SCM ans
= SCM_MAKINUM((long)u
);
3719 if (SCM_INUM(ans
)==(long)u
) return ans
;
3721 SCM_ASRTGO(!IS_INF(u
), badz
); /* problem? */
3722 return scm_dbl2big(u
);
3725 return SCM_MAKINUM((long)floor(SCM_REALPART(z
)+0.5));
3731 #else /* ~SCM_FLOATS */
3732 SCM_PROC(s_trunc
, "truncate", 1, 0, 0, scm_trunc
);
3742 SCM_ASSERT(SCM_INUMP(x
), x
, SCM_ARG1
, s_truncate
);
3748 #endif /* SCM_FLOATS */
3752 /* d must be integer */
3755 scm_dbl2big(double d
)
3766 double u
= (d
< 0)?-d
:d
;
3767 while (0 != floor(u
)) {u
/= SCM_BIGRAD
;i
++;}
3768 ans
= scm_mkbig(i
, d
< 0);
3769 digits
= SCM_BDIGITS(ans
);
3778 scm_num_overflow ("dbl2big");
3795 scm_sizet i
= SCM_NUMDIGS(b
);
3796 SCM_BIGDIG
*digits
= SCM_BDIGITS(b
);
3797 while (i
--) ans
= digits
[i
] + SCM_BIGRAD
*ans
;
3798 if (scm_tc16_bigneg
==SCM_TYP16(b
)) return -ans
;
3806 scm_long2num(long sl
)
3813 if (!SCM_FIXABLE(sl
)) {
3815 return scm_long2big(sl
);
3818 return scm_makdbl((double) sl
, 0.0);
3824 return SCM_MAKINUM(sl
);
3831 scm_long_long2num(long_long sl
)
3834 scm_long_long2num(sl
)
3838 if (!SCM_FIXABLE(sl
)) {
3840 return scm_long_long2big(sl
);
3843 return scm_makdbl((double) sl
, 0.0);
3849 return SCM_MAKINUM(sl
);
3856 scm_ulong2num(unsigned long sl
)
3863 if (!SCM_POSFIXABLE(sl
)) {
3865 return scm_ulong2big(sl
);
3868 return scm_makdbl((double) sl
, 0.0);
3874 return SCM_MAKINUM(sl
);
3879 scm_num2long(SCM num
, char *pos
, char *s_caller
)
3882 scm_num2long(num
, pos
, s_caller
)
3891 res
= SCM_INUM(num
);
3894 SCM_ASRTGO(SCM_NIMP(num
), errout
);
3898 double u
= SCM_REALPART(num
);
3900 if ((double)res
== u
)
3907 if (SCM_BIGP(num
)) {
3912 for(l
= SCM_NUMDIGS(num
);l
--;)
3914 res
= SCM_BIGUP(res
) + SCM_BDIGITS(num
)[l
];
3919 if (SCM_TYP16 (num
) == scm_tc16_bigpos
)
3925 errout
: scm_wta(num
, pos
, s_caller
);
3926 return SCM_UNSPECIFIED
;
3934 num2long(SCM num
, char *pos
, char *s_caller
)
3937 num2long(num
, pos
, s_caller
)
3945 res
= SCM_INUM((long)num
);
3948 SCM_ASRTGO(SCM_NIMP(num
), errout
);
3951 double u
= SCM_REALPART(num
);
3952 if (((SCM_MOST_NEGATIVE_FIXNUM
* 4) <= u
)
3953 && (u
<= (SCM_MOST_POSITIVE_FIXNUM
* 4 + 3))) {
3961 scm_sizet l
= SCM_NUMDIGS(num
);
3962 SCM_ASRTGO(SCM_DIGSPERLONG
>= l
, errout
);
3964 for(;l
--;) res
= SCM_BIGUP(res
) + SCM_BDIGITS(num
)[l
];
3968 errout
: scm_wta(num
, pos
, s_caller
);
3969 return SCM_UNSPECIFIED
;
3976 scm_num2long_long(SCM num
, char *pos
, char *s_caller
)
3979 scm_num2long_long(num
, pos
, s_caller
)
3987 res
= SCM_INUM((long_long
)num
);
3990 SCM_ASRTGO(SCM_NIMP(num
), errout
);
3993 double u
= SCM_REALPART(num
);
3994 if (((SCM_MOST_NEGATIVE_FIXNUM
* 4) <= u
)
3995 && (u
<= (SCM_MOST_POSITIVE_FIXNUM
* 4 + 3))) {
4003 scm_sizet l
= SCM_NUMDIGS(num
);
4004 SCM_ASRTGO(SCM_DIGSPERLONGLONG
>= l
, errout
);
4006 for(;l
--;) res
= SCM_LONGLONGBIGUP(res
) + SCM_BDIGITS(num
)[l
];
4010 errout
: scm_wta(num
, pos
, s_caller
);
4011 return SCM_UNSPECIFIED
;
4018 scm_num2ulong(SCM num
, char *pos
, char *s_caller
)
4021 scm_num2ulong(num
, pos
, s_caller
)
4030 res
= SCM_INUM((unsigned long)num
);
4033 SCM_ASRTGO(SCM_NIMP(num
), errout
);
4037 double u
= SCM_REALPART(num
);
4038 if ((0 <= u
) && (u
<= (unsigned long)~0L))
4046 if (SCM_BIGP(num
)) {
4047 unsigned long oldres
;
4051 for(l
= SCM_NUMDIGS(num
);l
--;)
4053 res
= SCM_BIGUP(res
) + SCM_BDIGITS(num
)[l
];
4061 errout
: scm_wta(num
, pos
, s_caller
);
4062 return SCM_UNSPECIFIED
;
4068 static void add1(f
, fsum
)
4079 scm_init_numbers (void)
4086 SCM_NEWCELL(scm_flo0
);
4088 SCM_CAR(scm_flo0
) = scm_tc_flo
;
4089 SCM_FLO(scm_flo0
) = 0.0;
4091 SCM_CDR(scm_flo0
) = (SCM
)scm_must_malloc(1L*sizeof(double), "real");
4092 SCM_REAL(scm_flo0
) = 0.0;
4093 SCM_CAR(scm_flo0
) = scm_tc_dblr
;
4096 scm_dblprec
= (DBL_DIG
> 20) ? 20 : DBL_DIG
;
4098 { /* determine floating point precision */
4100 double fsum
= 1.0+f
;
4101 while (fsum
!= 1.0) {
4103 if (++scm_dblprec
> 20) break;
4106 scm_dblprec
= scm_dblprec
-1;
4108 # endif /* DBL_DIG */
4110 #include "numbers.x"