1 /* Copyright (C) 1995,1996,1997,1998 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 */
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
);
94 if (SCM_NIMP (x
) && SCM_BIGP (x
))
100 SCM_PROC (s_odd_p
, "odd?", 1, 0, 0, scm_odd_p
);
109 SCM_ASSERT (SCM_NIMP (n
) && SCM_BIGP (n
), n
, SCM_ARG1
, s_odd_p
);
110 return (1 & SCM_BDIGITS (n
)[0]) ? SCM_BOOL_T
: SCM_BOOL_F
;
113 SCM_ASSERT (SCM_INUMP (n
), n
, SCM_ARG1
, s_odd_p
);
115 return (4 & (int) n
) ? SCM_BOOL_T
: SCM_BOOL_F
;
118 SCM_PROC (s_even_p
, "even?", 1, 0, 0, scm_even_p
);
127 SCM_ASSERT (SCM_NIMP (n
) && SCM_BIGP (n
), n
, SCM_ARG1
, s_even_p
);
128 return (1 & SCM_BDIGITS (n
)[0]) ? SCM_BOOL_F
: SCM_BOOL_T
;
131 SCM_ASSERT (SCM_INUMP (n
), n
, SCM_ARG1
, s_even_p
);
133 return (4 & (int) n
) ? SCM_BOOL_F
: SCM_BOOL_T
;
136 SCM_PROC (s_abs
, "abs", 1, 0, 0, scm_abs
);
145 SCM_ASSERT (SCM_NIMP (x
) && SCM_BIGP (x
), x
, SCM_ARG1
, s_abs
);
146 if (SCM_TYP16 (x
) == scm_tc16_bigpos
)
148 return scm_copybig (x
, 0);
151 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_abs
);
153 if (SCM_INUM (x
) >= 0)
156 if (!SCM_POSFIXABLE (x
))
158 return scm_long2big (x
);
160 scm_num_overflow (s_abs
);
162 return SCM_MAKINUM (x
);
165 SCM_PROC (s_quotient
, "quotient", 2, 0, 0, scm_quotient
);
177 SCM_ASSERT (SCM_NIMP (x
) && SCM_BIGP (x
), x
, SCM_ARG1
, s_quotient
);
180 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
181 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
182 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
183 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
), 2);
193 w
= scm_copybig (x
, SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0));
194 scm_divbigdig (SCM_BDIGITS (w
), SCM_NUMDIGS (w
), (SCM_BIGDIG
) z
);
195 return scm_normbig (w
);
197 #ifndef SCM_DIGSTOOBIG
198 w
= scm_pseudolong (z
);
199 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
200 (SCM_BIGDIG
*) & w
, SCM_DIGSPERLONG
,
201 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 2);
204 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
205 scm_longdigs (z
, zdigs
);
206 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
207 zdigs
, SCM_DIGSPERLONG
,
208 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 2);
215 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
218 scm_wta (y
, (char *) SCM_ARG2
, s_quotient
);
224 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_quotient
);
225 SCM_ASSERT (SCM_INUMP (y
), y
, SCM_ARG2
, s_quotient
);
227 if ((z
= SCM_INUM (y
)) == 0)
230 scm_num_overflow (s_quotient
);
232 z
= SCM_INUM (x
) / z
;
235 #if (__TURBOC__ == 1)
236 long t
= ((y
< 0) ? -SCM_INUM (x
) : SCM_INUM (x
)) % SCM_INUM (y
);
238 long t
= SCM_INUM (x
) % SCM_INUM (y
);
249 if (!SCM_FIXABLE (z
))
251 return scm_long2big (z
);
253 scm_num_overflow (s_quotient
);
255 return SCM_MAKINUM (z
);
258 SCM_PROC (s_remainder
, "remainder", 2, 0, 0, scm_remainder
);
269 SCM_ASSERT (SCM_NIMP (x
) && SCM_BIGP (x
), x
, SCM_ARG1
, s_remainder
);
272 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
273 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
274 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
277 if (!(z
= SCM_INUM (y
)))
279 return scm_divbigint (x
, z
, SCM_BIGSIGN (x
), 0);
284 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
287 scm_wta (y
, (char *) SCM_ARG2
, s_remainder
);
293 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_remainder
);
294 SCM_ASSERT (SCM_INUMP (y
), y
, SCM_ARG2
, s_remainder
);
296 if (!(z
= SCM_INUM (y
)))
299 scm_num_overflow (s_remainder
);
301 #if (__TURBOC__ == 1)
305 z
= SCM_INUM (x
) % z
;
315 return SCM_MAKINUM (z
);
318 SCM_PROC (s_modulo
, "modulo", 2, 0, 0, scm_modulo
);
329 SCM_ASSERT (SCM_NIMP (x
) && SCM_BIGP (x
), x
, SCM_ARG1
, s_modulo
);
332 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
333 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
334 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
336 (SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
)) ? 1 : 0);
338 if (!(z
= SCM_INUM (y
)))
340 return scm_divbigint (x
, z
, y
< 0,
341 (SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0)) ? 1 : 0);
346 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
349 scm_wta (y
, (char *) SCM_ARG2
, s_modulo
);
352 return (SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0)) ? scm_sum (x
, y
) : x
;
355 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_modulo
);
356 SCM_ASSERT (SCM_INUMP (y
), y
, SCM_ARG2
, s_modulo
);
358 if (!(yy
= SCM_INUM (y
)))
361 scm_num_overflow (s_modulo
);
365 z
= ((yy
< 0) ? -z
: z
) % yy
;
367 z
= SCM_INUM (x
) % yy
;
369 return SCM_MAKINUM (((yy
< 0) ? (z
> 0) : (z
< 0)) ? z
+ yy
: z
);
372 SCM_PROC1 (s_gcd
, "gcd", scm_tc7_asubr
, scm_gcd
);
379 register long u
, v
, k
, t
;
381 return SCM_UNBNDP (x
) ? SCM_INUM0
: x
;
387 SCM_ASSERT (SCM_NIMP (x
) && SCM_BIGP (x
), x
, SCM_ARG1
, s_gcd
);
389 x
= scm_copybig (x
, 0);
393 SCM_ASSERT (SCM_NIMP (y
) && SCM_BIGP (y
), y
, SCM_ARG2
, s_gcd
);
395 y
= scm_copybig (y
, 0);
396 switch (scm_bigcomp (x
, y
))
400 t
= scm_remainder (x
, y
);
407 y
= scm_remainder (y
, x
);
410 /* instead of the switch, we could just
411 return scm_gcd (y, scm_modulo (x, y)); */
425 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_gcd
);
426 SCM_ASSERT (SCM_INUMP (y
), y
, SCM_ARG2
, s_gcd
);
441 for (k
= 1; !(1 & ((int) u
| (int) v
)); k
<<= 1, u
>>= 1, v
>>= 1);
460 if (!SCM_POSFIXABLE (u
))
462 return scm_long2big (u
);
464 scm_num_overflow (s_gcd
);
466 return SCM_MAKINUM (u
);
469 SCM_PROC1 (s_lcm
, "lcm", scm_tc7_asubr
, scm_lcm
);
479 n2
= SCM_MAKINUM (1L);
483 d
= scm_gcd (n1
, n2
);
486 return scm_abs (scm_product (n1
, scm_quotient (n2
, d
)));
491 #define scm_long2num SCM_MAKINUM
496 SCM_PROC1 (s_logand
, "logand", scm_tc7_asubr
, scm_logand
);
506 return SCM_MAKINUM (-1);
509 return scm_ulong2num (scm_num2ulong (n1
, (char *) SCM_ARG1
, s_logand
)
510 & scm_num2ulong (n2
, (char *) SCM_ARG2
, s_logand
));
513 SCM_PROC1 (s_logior
, "logior", scm_tc7_asubr
, scm_logior
);
526 return scm_ulong2num (scm_num2ulong (n1
, (char *) SCM_ARG1
, s_logior
)
527 | scm_num2ulong (n2
, (char *) SCM_ARG2
, s_logior
));
530 SCM_PROC1 (s_logxor
, "logxor", scm_tc7_asubr
, scm_logxor
);
543 return scm_ulong2num (scm_num2ulong (n1
, (char *) SCM_ARG1
, s_logxor
)
544 ^ scm_num2ulong (n2
, (char *) SCM_ARG2
, s_logxor
));
547 SCM_PROC (s_logtest
, "logtest", 2, 0, 0, scm_logtest
);
554 return ((scm_num2ulong (n1
, (char *) SCM_ARG1
, s_logtest
)
555 & scm_num2ulong (n2
, (char *) SCM_ARG2
, s_logtest
))
556 ? SCM_BOOL_T
: SCM_BOOL_F
);
560 SCM_PROC (s_logbit_p
, "logbit?", 2, 0, 0, scm_logbit_p
);
563 scm_logbit_p (n1
, n2
)
567 return (((1 << scm_num2long (n1
, (char *) SCM_ARG1
, s_logtest
))
568 & scm_num2ulong (n2
, (char *) SCM_ARG2
, s_logtest
))
569 ? SCM_BOOL_T
: SCM_BOOL_F
);
574 SCM_PROC1 (s_logand
, "logand", scm_tc7_asubr
, scm_logand
);
584 return SCM_MAKINUM (-1);
587 return SCM_MAKINUM (SCM_INUM (n1
) & SCM_INUM (n2
));
590 SCM_PROC1 (s_logior
, "logior", scm_tc7_asubr
, scm_logior
);
603 return SCM_MAKINUM (SCM_INUM (n1
) | SCM_INUM (n2
));
606 SCM_PROC1 (s_logxor
, "logxor", scm_tc7_asubr
, scm_logxor
);
619 return SCM_MAKINUM (SCM_INUM (n1
) ^ SCM_INUM (n2
));
622 SCM_PROC (s_logtest
, "logtest", 2, 0, 0, scm_logtest
);
629 SCM_ASSERT (SCM_INUMP (n1
), n1
, SCM_ARG1
, s_logtest
);
630 SCM_ASSERT (SCM_INUMP (n2
), n2
, SCM_ARG2
, s_logtest
);
631 return (SCM_INUM (n1
) & SCM_INUM (n2
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
634 SCM_PROC (s_logbit_p
, "logbit?", 2, 0, 0, scm_logbit_p
);
637 scm_logbit_p (n1
, n2
)
641 SCM_ASSERT (SCM_INUMP (n1
) && SCM_INUM (n1
) >= 0, n1
, SCM_ARG1
, s_logbit_p
);
642 SCM_ASSERT (SCM_INUMP (n2
), n2
, SCM_ARG2
, s_logbit_p
);
643 return ((1 << SCM_INUM (n1
)) & SCM_INUM (n2
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
647 SCM_PROC (s_lognot
, "lognot", 1, 0, 0, scm_lognot
);
653 SCM_ASSERT (SCM_INUMP (n
), n
, SCM_ARG1
, s_lognot
);
654 return scm_difference (SCM_MAKINUM (-1L), n
);
657 SCM_PROC (s_integer_expt
, "integer-expt", 2, 0, 0, scm_integer_expt
);
660 scm_integer_expt (z1
, z2
)
664 SCM acc
= SCM_MAKINUM (1L);
666 if (SCM_INUM0
== z1
|| acc
== z1
)
668 else if (SCM_MAKINUM (-1L) == z1
)
669 return SCM_BOOL_F
== scm_even_p (z2
) ? z1
: acc
;
671 SCM_ASSERT (SCM_INUMP (z2
), z2
, SCM_ARG2
, s_integer_expt
);
676 z1
= scm_divide (z1
, SCM_UNDEFINED
);
683 return scm_product (acc
, z1
);
685 acc
= scm_product (acc
, z1
);
686 z1
= scm_product (z1
, z1
);
691 SCM_PROC (s_ash
, "ash", 2, 0, 0, scm_ash
);
698 SCM res
= SCM_INUM (n
);
699 SCM_ASSERT (SCM_INUMP (cnt
), cnt
, SCM_ARG2
, s_ash
);
703 res
= scm_integer_expt (SCM_MAKINUM (2), SCM_MAKINUM (-SCM_INUM (cnt
)));
704 if (SCM_NFALSEP (scm_negative_p (n
)))
705 return scm_sum (SCM_MAKINUM (-1L),
706 scm_quotient (scm_sum (SCM_MAKINUM (1L), n
), res
));
708 return scm_quotient (n
, res
);
711 return scm_product (n
, scm_integer_expt (SCM_MAKINUM (2), cnt
));
713 SCM_ASSERT (SCM_INUMP (n
), n
, SCM_ARG1
, s_ash
);
714 cnt
= SCM_INUM (cnt
);
716 return SCM_MAKINUM (SCM_SRS (res
, -cnt
));
717 res
= SCM_MAKINUM (res
<< cnt
);
718 if (SCM_INUM (res
) >> cnt
!= SCM_INUM (n
))
719 scm_num_overflow (s_ash
);
724 SCM_PROC (s_bit_extract
, "bit-extract", 3, 0, 0, scm_bit_extract
);
727 scm_bit_extract (n
, start
, end
)
732 SCM_ASSERT (SCM_INUMP (start
), start
, SCM_ARG2
, s_bit_extract
);
733 SCM_ASSERT (SCM_INUMP (end
), end
, SCM_ARG3
, s_bit_extract
);
734 start
= SCM_INUM (start
);
735 end
= SCM_INUM (end
);
736 SCM_ASSERT (end
>= start
, SCM_MAKINUM (end
), SCM_OUTOFRANGE
, s_bit_extract
);
740 scm_logand (scm_difference (scm_integer_expt (SCM_MAKINUM (2),
741 SCM_MAKINUM (end
- start
)),
743 scm_ash (n
, SCM_MAKINUM (-start
)));
745 SCM_ASSERT (SCM_INUMP (n
), n
, SCM_ARG1
, s_bit_extract
);
747 return SCM_MAKINUM ((SCM_INUM (n
) >> start
) & ((1L << (end
- start
)) - 1));
750 char scm_logtab
[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
751 SCM_PROC (s_logcount
, "logcount", 1, 0, 0, scm_logcount
);
757 register unsigned long c
= 0;
764 SCM_ASSERT (SCM_NIMP (n
) && SCM_BIGP (n
), n
, SCM_ARG1
, s_logcount
);
766 return scm_logcount (scm_difference (SCM_MAKINUM (-1L), n
));
767 ds
= SCM_BDIGITS (n
);
768 for (i
= SCM_NUMDIGS (n
); i
--;)
769 for (d
= ds
[i
]; d
; d
>>= 4)
770 c
+= scm_logtab
[15 & d
];
771 return SCM_MAKINUM (c
);
774 SCM_ASSERT (SCM_INUMP (n
), n
, SCM_ARG1
, s_logcount
);
776 if ((nn
= SCM_INUM (n
)) < 0)
779 c
+= scm_logtab
[15 & nn
];
780 return SCM_MAKINUM (c
);
783 char scm_ilentab
[] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 };
784 SCM_PROC (s_integer_length
, "integer-length", 1, 0, 0, scm_integer_length
);
787 scm_integer_length (n
)
790 register unsigned long c
= 0;
797 SCM_ASSERT (SCM_NIMP (n
) && SCM_BIGP (n
), n
, SCM_ARG1
, s_integer_length
);
799 return scm_integer_length (scm_difference (SCM_MAKINUM (-1L), n
));
800 ds
= SCM_BDIGITS (n
);
801 d
= ds
[c
= SCM_NUMDIGS (n
) - 1];
802 for (c
*= SCM_BITSPERDIG
; d
; d
>>= 4)
805 l
= scm_ilentab
[15 & d
];
807 return SCM_MAKINUM (c
- 4 + l
);
810 SCM_ASSERT (SCM_INUMP (n
), n
, SCM_ARG1
, s_integer_length
);
812 if ((nn
= SCM_INUM (n
)) < 0)
817 l
= scm_ilentab
[15 & nn
];
819 return SCM_MAKINUM (c
- 4 + l
);
824 char scm_s_bignum
[] = "bignum";
827 scm_mkbig (nlen
, sign
)
832 /* Cast to SCM to avoid signed/unsigned comparison warnings. */
833 if (((v
<< 16) >> 16) != (SCM
) nlen
)
834 scm_wta (SCM_MAKINUM (nlen
), (char *) SCM_NALLOC
, scm_s_bignum
);
837 SCM_SETCHARS (v
, scm_must_malloc ((long) (nlen
* sizeof (SCM_BIGDIG
)),
839 SCM_SETNUMDIGS (v
, nlen
, sign
? scm_tc16_bigneg
: scm_tc16_bigpos
);
850 unsigned long num
= 0;
851 SCM_BIGDIG
*tmp
= SCM_BDIGITS (b
);
853 num
= SCM_BIGUP (num
) + tmp
[l
];
854 if (SCM_TYP16 (b
) == scm_tc16_bigpos
)
856 if (SCM_POSFIXABLE (num
))
857 return SCM_MAKINUM (num
);
859 else if (SCM_UNEGFIXABLE (num
))
860 return SCM_MAKINUM (-num
);
865 char s_adjbig
[] = "scm_adjbig";
872 scm_sizet nsiz
= nlen
;
873 if (((nsiz
<< 16) >> 16) != nlen
)
874 scm_wta (scm_ulong2num (nsiz
), (char *) SCM_NALLOC
, s_adjbig
);
880 scm_must_realloc ((char *) SCM_CHARS (b
),
881 (long) (SCM_NUMDIGS (b
) * sizeof (SCM_BIGDIG
)),
882 (long) (nsiz
* sizeof (SCM_BIGDIG
)), s_adjbig
));
884 SCM_SETCHARS (b
, digits
);
885 SCM_SETNUMDIGS (b
, nsiz
, SCM_TYP16 (b
));
898 scm_sizet nlen
= SCM_NUMDIGS (b
);
900 int nlen
= SCM_NUMDIGS (b
); /* unsigned nlen breaks on Cray when nlen => 0 */
902 SCM_BIGDIG
*zds
= SCM_BDIGITS (b
);
903 while (nlen
-- && !zds
[nlen
]);
905 if (nlen
* SCM_BITSPERDIG
/ SCM_CHAR_BIT
<= sizeof (SCM
))
906 if (SCM_INUMP (b
= scm_big2inum (b
, (scm_sizet
) nlen
)))
908 if (SCM_NUMDIGS (b
) == nlen
)
910 return scm_adjbig (b
, (scm_sizet
) nlen
);
916 scm_copybig (b
, sign
)
920 scm_sizet i
= SCM_NUMDIGS (b
);
921 SCM ans
= scm_mkbig (i
, sign
);
922 SCM_BIGDIG
*src
= SCM_BDIGITS (b
), *dst
= SCM_BDIGITS (ans
);
936 SCM ans
= scm_mkbig (SCM_DIGSPERLONG
, n
< 0);
937 digits
= SCM_BDIGITS (ans
);
940 while (i
< SCM_DIGSPERLONG
)
942 digits
[i
++] = SCM_BIGLO (n
);
943 n
= SCM_BIGDN ((unsigned long) n
);
951 scm_long_long2big (n
)
962 if ((long long) tn
== n
)
963 return scm_long2big (tn
);
969 for (tn
= n
, n_digits
= 0;
971 ++n_digits
, tn
= SCM_BIGDN ((ulong_long
) tn
))
976 ans
= scm_mkbig (n_digits
, n
< 0);
977 digits
= SCM_BDIGITS (ans
);
982 digits
[i
++] = SCM_BIGLO (n
);
983 n
= SCM_BIGDN ((ulong_long
) n
);
999 ans
= scm_mkbig (2 * SCM_DIGSPERLONG
, 0);
1000 digits
= SCM_BDIGITS (ans
);
1003 for (i
= 0; i
< SCM_DIGSPERLONG
; ++i
)
1005 digits
[i
] = SCM_BIGLO (n
);
1006 n
= SCM_BIGDN ((unsigned long) n
);
1009 for (i
= 0; i
< SCM_DIGSPERLONG
; ++i
)
1011 digits
[i
+ SCM_DIGSPERLONG
] = SCM_BIGLO (n
);
1012 n
= SCM_BIGDN ((unsigned long) n
);
1025 SCM ans
= scm_mkbig (SCM_DIGSPERLONG
, 0);
1026 digits
= SCM_BDIGITS (ans
);
1027 while (i
< SCM_DIGSPERLONG
)
1029 digits
[i
++] = SCM_BIGLO (n
);
1042 int xsign
= SCM_BIGSIGN (x
);
1043 int ysign
= SCM_BIGSIGN (y
);
1044 scm_sizet xlen
, ylen
;
1046 /* Look at the signs, first. */
1052 /* They're the same sign, so see which one has more digits. Note
1053 that, if they are negative, the longer number is the lesser. */
1054 ylen
= SCM_NUMDIGS (y
);
1055 xlen
= SCM_NUMDIGS (x
);
1057 return (xsign
) ? -1 : 1;
1059 return (xsign
) ? 1 : -1;
1061 /* They have the same number of digits, so find the most significant
1062 digit where they differ. */
1066 if (SCM_BDIGITS (y
)[xlen
] != SCM_BDIGITS (x
)[xlen
])
1067 /* Make the discrimination based on the digit that differs. */
1068 return ((SCM_BDIGITS (y
)[xlen
] > SCM_BDIGITS (x
)[xlen
])
1070 : (xsign
? 1 : -1));
1073 /* The numbers are identical. */
1077 #ifndef SCM_DIGSTOOBIG
1087 SCM_BIGDIG bd
[SCM_DIGSPERLONG
];
1093 while (i
< SCM_DIGSPERLONG
)
1095 p
.bd
[i
++] = SCM_BIGLO (x
);
1098 /* p.bd[0] = SCM_BIGLO(x); p.bd[1] = SCM_BIGDN(x); */
1106 scm_longdigs (x
, digs
)
1113 while (i
< SCM_DIGSPERLONG
)
1115 digs
[i
++] = SCM_BIGLO (x
);
1124 scm_addbig (x
, nx
, xsgn
, bigy
, sgny
)
1131 /* Assumes nx <= SCM_NUMDIGS(bigy) */
1132 /* Assumes xsgn and sgny scm_equal either 0 or 0x0100 */
1134 scm_sizet i
= 0, ny
= SCM_NUMDIGS (bigy
);
1135 SCM z
= scm_copybig (bigy
, SCM_BIGSIGN (bigy
) ^ sgny
);
1136 SCM_BIGDIG
*zds
= SCM_BDIGITS (z
);
1137 if (xsgn
^ SCM_BIGSIGN (z
))
1141 num
+= (long) zds
[i
] - x
[i
];
1144 zds
[i
] = num
+ SCM_BIGRAD
;
1149 zds
[i
] = SCM_BIGLO (num
);
1154 if (num
&& nx
== ny
)
1158 SCM_SETCAR (z
, SCM_CAR (z
) ^ 0x0100);
1161 num
+= (SCM_BIGRAD
- 1) - zds
[i
];
1162 zds
[i
++] = SCM_BIGLO (num
);
1163 num
= SCM_BIGDN (num
);
1173 zds
[i
++] = num
+ SCM_BIGRAD
;
1178 zds
[i
++] = SCM_BIGLO (num
);
1187 num
+= (long) zds
[i
] + x
[i
];
1188 zds
[i
++] = SCM_BIGLO (num
);
1189 num
= SCM_BIGDN (num
);
1197 zds
[i
++] = SCM_BIGLO (num
);
1198 num
= SCM_BIGDN (num
);
1204 z
= scm_adjbig (z
, ny
+ 1);
1205 SCM_BDIGITS (z
)[ny
] = num
;
1209 return scm_normbig (z
);
1214 scm_mulbig (x
, nx
, y
, ny
, sgn
)
1221 scm_sizet i
= 0, j
= nx
+ ny
;
1222 unsigned long n
= 0;
1223 SCM z
= scm_mkbig (j
, sgn
);
1224 SCM_BIGDIG
*zds
= SCM_BDIGITS (z
);
1234 n
+= zds
[i
+ j
] + ((unsigned long) x
[i
] * y
[j
]);
1235 zds
[i
+ j
++] = SCM_BIGLO (n
);
1247 return scm_normbig (z
);
1251 /* Sun's compiler complains about the fact that this function has an
1252 ANSI prototype in numbers.h, but a K&R declaration here, and the
1253 two specify different promotions for the third argument. I'm going
1254 to turn this into an ANSI declaration, and see if anyone complains
1255 about it not being K&R. */
1258 scm_divbigdig (SCM_BIGDIG
* ds
,
1262 register unsigned long t2
= 0;
1265 t2
= SCM_BIGUP (t2
) + ds
[h
];
1275 scm_divbigint (x
, z
, sgn
, mode
)
1285 register unsigned long t2
= 0;
1286 register SCM_BIGDIG
*ds
= SCM_BDIGITS (x
);
1287 scm_sizet nd
= SCM_NUMDIGS (x
);
1289 t2
= (SCM_BIGUP (t2
) + ds
[nd
]) % z
;
1292 return SCM_MAKINUM (sgn
? -t2
: t2
);
1295 #ifndef SCM_DIGSTOOBIG
1296 unsigned long t2
= scm_pseudolong (z
);
1297 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
1298 (SCM_BIGDIG
*) & t2
, SCM_DIGSPERLONG
,
1301 SCM_BIGDIG t2
[SCM_DIGSPERLONG
];
1302 scm_longdigs (z
, t2
);
1303 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
1304 t2
, SCM_DIGSPERLONG
,
1312 scm_divbigbig (x
, nx
, y
, ny
, sgn
, modes
)
1320 /* modes description
1324 3 quotient but returns 0 if division is not exact. */
1325 scm_sizet i
= 0, j
= 0;
1327 unsigned long t2
= 0;
1329 SCM_BIGDIG d
= 0, qhat
, *zds
, *yds
;
1330 /* algorithm requires nx >= ny */
1334 case 0: /* remainder -- just return x */
1335 z
= scm_mkbig (nx
, sgn
);
1336 zds
= SCM_BDIGITS (z
);
1343 case 1: /* scm_modulo -- return y-x */
1344 z
= scm_mkbig (ny
, sgn
);
1345 zds
= SCM_BDIGITS (z
);
1348 num
+= (long) y
[i
] - x
[i
];
1351 zds
[i
] = num
+ SCM_BIGRAD
;
1366 zds
[i
++] = num
+ SCM_BIGRAD
;
1377 return SCM_INUM0
; /* quotient is zero */
1379 return 0; /* the division is not exact */
1382 z
= scm_mkbig (nx
== ny
? nx
+ 2 : nx
+ 1, sgn
);
1383 zds
= SCM_BDIGITS (z
);
1387 ny
--; /* in case y came in as a psuedolong */
1388 if (y
[ny
- 1] < (SCM_BIGRAD
>> 1))
1389 { /* normalize operands */
1390 d
= SCM_BIGRAD
/ (y
[ny
- 1] + 1);
1391 newy
= scm_mkbig (ny
, 0);
1392 yds
= SCM_BDIGITS (newy
);
1395 t2
+= (unsigned long) y
[j
] * d
;
1396 yds
[j
++] = SCM_BIGLO (t2
);
1397 t2
= SCM_BIGDN (t2
);
1404 t2
+= (unsigned long) x
[j
] * d
;
1405 zds
[j
++] = SCM_BIGLO (t2
);
1406 t2
= SCM_BIGDN (t2
);
1416 j
= nx
== ny
? nx
+ 1 : nx
; /* dividend needs more digits than divisor */
1418 { /* loop over digits of quotient */
1419 if (zds
[j
] == y
[ny
- 1])
1420 qhat
= SCM_BIGRAD
- 1;
1422 qhat
= (SCM_BIGUP (zds
[j
]) + zds
[j
- 1]) / y
[ny
- 1];
1429 { /* multiply and subtract */
1430 t2
+= (unsigned long) y
[i
] * qhat
;
1431 num
+= zds
[j
- ny
+ i
] - SCM_BIGLO (t2
);
1434 zds
[j
- ny
+ i
] = num
+ SCM_BIGRAD
;
1439 zds
[j
- ny
+ i
] = num
;
1442 t2
= SCM_BIGDN (t2
);
1445 num
+= zds
[j
- ny
+ i
] - t2
; /* borrow from high digit; don't update */
1447 { /* "add back" required */
1453 num
+= (long) zds
[j
- ny
+ i
] + y
[i
];
1454 zds
[j
- ny
+ i
] = SCM_BIGLO (num
);
1455 num
= SCM_BIGDN (num
);
1466 case 3: /* check that remainder==0 */
1467 for (j
= ny
; j
&& !zds
[j
- 1]; --j
);
1470 case 2: /* move quotient down in z */
1471 j
= (nx
== ny
? nx
+ 2 : nx
+ 1) - ny
;
1472 for (i
= 0; i
< j
; i
++)
1473 zds
[i
] = zds
[i
+ ny
];
1476 case 1: /* subtract for scm_modulo */
1482 num
+= y
[i
] - zds
[i
];
1486 zds
[i
] = num
+ SCM_BIGRAD
;
1498 case 0: /* just normalize remainder */
1500 scm_divbigdig (zds
, ny
, d
);
1503 for (j
= ny
; j
&& !zds
[j
- 1]; --j
);
1504 if (j
* SCM_BITSPERDIG
<= sizeof (SCM
) * SCM_CHAR_BIT
)
1505 if (SCM_INUMP (z
= scm_big2inum (z
, j
)))
1507 return scm_adjbig (z
, j
);
1515 /*** NUMBERS -> STRINGS ***/
1518 static double fx
[] =
1519 { 0.0, 5e-1, 5e-2, 5e-3, 5e-4, 5e-5,
1520 5e-6, 5e-7, 5e-8, 5e-9, 5e-10,
1521 5e-11, 5e-12, 5e-13, 5e-14, 5e-15,
1522 5e-16, 5e-17, 5e-18, 5e-19, 5e-20};
1527 static scm_sizet idbl2str
SCM_P ((double f
, char *a
));
1534 int efmt
, dpt
, d
, i
, wp
= scm_dblprec
;
1539 goto zero
; /*{a[0]='0'; a[1]='.'; a[2]='0'; return 3;} */
1558 #ifdef DBL_MIN_10_EXP /* Prevent unnormalized values, as from
1559 make-uniform-vector, from causing infinite loops. */
1563 if (exp
-- < DBL_MIN_10_EXP
)
1569 if (exp
++ > DBL_MAX_10_EXP
)
1584 if (f
+ fx
[wp
] >= 10.0)
1591 dpt
= (exp
+ 9999) % 3;
1595 efmt
= (exp
< -3) || (exp
> wp
+ 2);
1620 if (f
+ fx
[wp
] >= 1.0)
1634 if ((dpt
> 4) && (exp
> 6))
1636 d
= (a
[0] == '-' ? 2 : 1);
1637 for (i
= ch
++; i
> d
; i
--)
1650 if (a
[ch
- 1] == '.')
1651 a
[ch
++] = '0'; /* trailing zero */
1660 for (i
= 10; i
<= exp
; i
*= 10);
1661 for (i
/= 10; i
; i
/= 10)
1663 a
[ch
++] = exp
/ i
+ '0';
1671 static scm_sizet iflo2str
SCM_P ((SCM flt
, char *str
));
1680 if (SCM_SINGP (flt
))
1681 i
= idbl2str (SCM_FLO (flt
), str
);
1684 i
= idbl2str (SCM_REAL (flt
), str
);
1685 if (SCM_CPLXP (flt
))
1687 if (0 <= SCM_IMAG (flt
)) /* jeh */
1688 str
[i
++] = '+'; /* jeh */
1689 i
+= idbl2str (SCM_IMAG (flt
), &str
[i
]);
1694 #endif /* SCM_FLOATS */
1698 scm_iint2str (num
, rad
, p
)
1704 register int i
= 1, d
;
1705 register long n
= num
;
1711 for (n
/= rad
; n
> 0; n
/= rad
)
1725 p
[i
] = d
+ ((d
< 10) ? '0' : 'a' - 10);
1733 static SCM big2str
SCM_P ((SCM b
, register unsigned int radix
));
1738 register unsigned int radix
;
1740 SCM t
= scm_copybig (b
, 0); /* sign of temp doesn't matter */
1741 register SCM_BIGDIG
*ds
= SCM_BDIGITS (t
);
1742 scm_sizet i
= SCM_NUMDIGS (t
);
1743 scm_sizet j
= radix
== 16 ? (SCM_BITSPERDIG
* i
) / 4 + 2
1744 : radix
>= 10 ? (SCM_BITSPERDIG
* i
* 241L) / 800 + 2
1745 : (SCM_BITSPERDIG
* i
) + 2;
1747 scm_sizet radct
= 0;
1748 scm_sizet ch
; /* jeh */
1749 SCM_BIGDIG radpow
= 1, radmod
= 0;
1750 SCM ss
= scm_makstr ((long) j
, 0);
1751 char *s
= SCM_CHARS (ss
), c
;
1752 while ((long) radpow
* radix
< SCM_BIGRAD
)
1757 s
[0] = scm_tc16_bigneg
== SCM_TYP16 (b
) ? '-' : '+';
1758 while ((i
|| radmod
) && j
)
1762 radmod
= (SCM_BIGDIG
) scm_divbigdig (ds
, i
, radpow
);
1770 s
[--j
] = c
< 10 ? c
+ '0' : c
+ 'a' - 10;
1772 ch
= s
[0] == '-' ? 1 : 0; /* jeh */
1775 for (i
= j
; j
< SCM_LENGTH (ss
); j
++)
1776 s
[ch
+ j
- i
] = s
[j
]; /* jeh */
1777 scm_vector_set_length_x (ss
, /* jeh */
1778 (SCM
) SCM_MAKINUM (ch
+ SCM_LENGTH (ss
) - i
));
1781 return scm_return_first (ss
, t
);
1786 SCM_PROC (s_number_to_string
, "number->string", 1, 1, 0, scm_number_to_string
);
1789 scm_number_to_string (x
, radix
)
1793 if (SCM_UNBNDP (radix
))
1794 radix
= SCM_MAKINUM (10L);
1796 SCM_ASSERT (SCM_INUMP (radix
), radix
, SCM_ARG2
, s_number_to_string
);
1800 char num_buf
[SCM_FLOBUFLEN
];
1802 SCM_ASRTGO (SCM_NIMP (x
), badx
);
1804 return big2str (x
, (unsigned int) SCM_INUM (radix
));
1805 #ifndef SCM_RECKLESS
1806 if (!(SCM_INEXP (x
)))
1809 scm_wta (x
, (char *) SCM_ARG1
, s_number_to_string
);
1813 SCM_ASSERT (SCM_NIMP (x
) && SCM_INEXP (x
),
1814 x
, SCM_ARG1
, s_number_to_string
);
1816 return scm_makfromstr (num_buf
, iflo2str (x
, num_buf
), 0);
1822 SCM_ASSERT (SCM_NIMP (x
) && SCM_BIGP (x
),
1823 x
, SCM_ARG1
, s_number_to_string
);
1824 return big2str (x
, (unsigned int) SCM_INUM (radix
));
1827 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_number_to_string
);
1831 char num_buf
[SCM_INTBUFLEN
];
1832 return scm_makfromstr (num_buf
,
1833 scm_iint2str (SCM_INUM (x
),
1834 (int) SCM_INUM (radix
),
1841 /* These print routines are stubbed here so that scm_repl.c doesn't need
1842 SCM_FLOATS or SCM_BIGDIGs conditionals */
1845 scm_floprint (sexp
, port
, pstate
)
1848 scm_print_state
*pstate
;
1851 char num_buf
[SCM_FLOBUFLEN
];
1852 scm_lfwrite (num_buf
, iflo2str (sexp
, num_buf
), port
);
1854 scm_ipruk ("float", sexp
, port
);
1862 scm_bigprint (exp
, port
, pstate
)
1865 scm_print_state
*pstate
;
1868 exp
= big2str (exp
, (unsigned int) 10);
1869 scm_lfwrite (SCM_CHARS (exp
), (scm_sizet
) SCM_LENGTH (exp
), port
);
1871 scm_ipruk ("bignum", exp
, port
);
1875 /*** END nums->strs ***/
1877 /*** STRINGS -> NUMBERS ***/
1879 static SCM scm_small_istr2int
SCM_P ((char *str
, long len
, long radix
));
1882 scm_small_istr2int (str
, len
, radix
)
1887 register long n
= 0, ln
;
1892 return SCM_BOOL_F
; /* zero scm_length */
1894 { /* leading sign */
1899 return SCM_BOOL_F
; /* bad if lone `+' or `-' */
1904 switch (c
= str
[i
++])
1926 return SCM_BOOL_F
; /* bad digit for radix */
1929 /* Negation is a workaround for HP700 cc bug */
1930 if (n
> ln
|| (-n
> -SCM_MOST_NEGATIVE_FIXNUM
))
1934 return SCM_BOOL_F
; /* not a digit */
1939 if ((n
= -n
) > SCM_MOST_POSITIVE_FIXNUM
)
1941 return SCM_MAKINUM (n
);
1942 ovfl
: /* overflow scheme integer */
1949 scm_istr2int (str
, len
, radix
)
1955 register scm_sizet k
, blen
= 1;
1959 register SCM_BIGDIG
*ds
;
1960 register unsigned long t2
;
1963 return SCM_BOOL_F
; /* zero scm_length */
1965 /* Short numbers we parse directly into an int, to avoid the overhead
1966 of creating a bignum. */
1968 return scm_small_istr2int (str
, len
, radix
);
1971 j
= 1 + (4 * len
* sizeof (char)) / (SCM_BITSPERDIG
);
1972 else if (10 <= radix
)
1973 j
= 1 + (84 * len
* sizeof (char)) / (SCM_BITSPERDIG
* 25);
1975 j
= 1 + (len
* sizeof (char)) / (SCM_BITSPERDIG
);
1977 { /* leading sign */
1980 if (++i
== (unsigned) len
)
1981 return SCM_BOOL_F
; /* bad if lone `+' or `-' */
1983 res
= scm_mkbig (j
, '-' == str
[0]);
1984 ds
= SCM_BDIGITS (res
);
1989 switch (c
= str
[i
++])
2011 return SCM_BOOL_F
; /* bad digit for radix */
2017 /* printf ("k = %d, blen = %d, t2 = %ld, ds[k] = %d\n", k, blen, t2, ds[k]); */
2018 t2
+= ds
[k
] * radix
;
2019 ds
[k
++] = SCM_BIGLO (t2
);
2020 t2
= SCM_BIGDN (t2
);
2023 scm_num_overflow ("bignum");
2031 return SCM_BOOL_F
; /* not a digit */
2034 while (i
< (unsigned) len
);
2035 if (blen
* SCM_BITSPERDIG
/ SCM_CHAR_BIT
<= sizeof (SCM
))
2036 if (SCM_INUMP (res
= scm_big2inum (res
, blen
)))
2040 return scm_adjbig (res
, blen
);
2046 scm_istr2flo (str
, len
, radix
)
2051 register int c
, i
= 0;
2053 double res
= 0.0, tmp
= 0.0;
2059 return SCM_BOOL_F
; /* zero scm_length */
2062 { /* leading sign */
2075 return SCM_BOOL_F
; /* bad if lone `+' or `-' */
2077 if (str
[i
] == 'i' || str
[i
] == 'I')
2078 { /* handle `+i' and `-i' */
2079 if (lead_sgn
== 0.0)
2080 return SCM_BOOL_F
; /* must have leading sign */
2082 return SCM_BOOL_F
; /* `i' not last character */
2083 return scm_makdbl (0.0, lead_sgn
);
2086 { /* check initial digits */
2096 goto out1
; /* must be exponent */
2113 return SCM_BOOL_F
; /* bad digit for radix */
2114 res
= res
* radix
+ c
;
2115 flg
= 1; /* res is valid */
2124 /* if true, then we did see a digit above, and res is valid */
2128 /* By here, must have seen a digit,
2129 or must have next char be a `.' with radix==10 */
2131 if (!(str
[i
] == '.' && radix
== 10))
2134 while (str
[i
] == '#')
2135 { /* optional sharps */
2168 tmp
= tmp
* radix
+ c
;
2176 return SCM_BOOL_F
; /* `slash zero' not allowed */
2178 while (str
[i
] == '#')
2179 { /* optional sharps */
2189 { /* decimal point notation */
2191 return SCM_BOOL_F
; /* must be radix 10 */
2198 res
= res
* 10.0 + c
- '0';
2207 return SCM_BOOL_F
; /* no digits before or after decimal point */
2210 while (str
[i
] == '#')
2211 { /* ignore remaining sharps */
2230 int expsgn
= 1, expon
= 0;
2232 return SCM_BOOL_F
; /* only in radix 10 */
2234 return SCM_BOOL_F
; /* bad exponent */
2241 return SCM_BOOL_F
; /* bad exponent */
2243 if (str
[i
] < '0' || str
[i
] > '9')
2244 return SCM_BOOL_F
; /* bad exponent */
2250 expon
= expon
* 10 + c
- '0';
2252 return SCM_BOOL_F
; /* exponent too large */
2260 point
+= expsgn
* expon
;
2278 /* at this point, we have a legitimate floating point result */
2279 if (lead_sgn
== -1.0)
2282 return scm_makdbl (res
, 0.0);
2284 if (str
[i
] == 'i' || str
[i
] == 'I')
2285 { /* pure imaginary number */
2286 if (lead_sgn
== 0.0)
2287 return SCM_BOOL_F
; /* must have leading sign */
2289 return SCM_BOOL_F
; /* `i' not last character */
2290 return scm_makdbl (0.0, res
);
2302 { /* polar input for complex number */
2303 /* get a `real' for scm_angle */
2304 second
= scm_istr2flo (&str
[i
], (long) (len
- i
), radix
);
2305 if (!(SCM_INEXP (second
)))
2306 return SCM_BOOL_F
; /* not `real' */
2307 if (SCM_CPLXP (second
))
2308 return SCM_BOOL_F
; /* not `real' */
2309 tmp
= SCM_REALPART (second
);
2310 return scm_makdbl (res
* cos (tmp
), res
* sin (tmp
));
2316 /* at this point, last char must be `i' */
2317 if (str
[len
- 1] != 'i' && str
[len
- 1] != 'I')
2319 /* handles `x+i' and `x-i' */
2321 return scm_makdbl (res
, lead_sgn
);
2322 /* get a `ureal' for complex part */
2323 second
= scm_istr2flo (&str
[i
], (long) ((len
- i
) - 1), radix
);
2324 if (!(SCM_INEXP (second
)))
2325 return SCM_BOOL_F
; /* not `ureal' */
2326 if (SCM_CPLXP (second
))
2327 return SCM_BOOL_F
; /* not `ureal' */
2328 tmp
= SCM_REALPART (second
);
2330 return SCM_BOOL_F
; /* not `ureal' */
2331 return scm_makdbl (res
, (lead_sgn
* tmp
));
2333 #endif /* SCM_FLOATS */
2338 scm_istring2number (str
, len
, radix
)
2345 char ex_p
= 0, rx_p
= 0; /* Only allow 1 exactness and 1 radix prefix */
2348 if (*str
== '+' || *str
== '-') /* Catches lone `+' and `-' for speed */
2351 while ((len
- i
) >= 2 && str
[i
] == '#' && ++i
)
2397 return scm_istr2int (&str
[i
], len
- i
, radix
);
2399 res
= scm_istr2int (&str
[i
], len
- i
, radix
);
2400 if (SCM_NFALSEP (res
))
2404 return scm_istr2flo (&str
[i
], len
- i
, radix
);
2411 SCM_PROC (s_string_to_number
, "string->number", 1, 1, 0, scm_string_to_number
);
2414 scm_string_to_number (str
, radix
)
2419 if (SCM_UNBNDP (radix
))
2420 radix
= SCM_MAKINUM (10L);
2422 SCM_ASSERT (SCM_INUMP (radix
), radix
, SCM_ARG2
, s_string_to_number
);
2423 SCM_ASSERT (SCM_NIMP (str
) && SCM_ROSTRINGP (str
),
2424 str
, SCM_ARG1
, s_string_to_number
);
2425 answer
= scm_istring2number (SCM_ROCHARS (str
),
2428 return scm_return_first (answer
, str
);
2430 /*** END strs->nums ***/
2440 if ((y
== 0.0) && (x
== 0.0))
2448 #ifndef SCM_SINGLESONLY
2449 if ((-FLTMAX
< x
) && (x
< FLTMAX
) && (fx
== x
))
2452 SCM_SETCAR (z
, scm_tc_flo
);
2457 #endif /* def SCM_SINGLES */
2458 SCM_SETCDR (z
, (SCM
) scm_must_malloc (1L * sizeof (double), "real"));
2459 SCM_SETCAR (z
, scm_tc_dblr
);
2463 SCM_SETCDR (z
, (SCM
) scm_must_malloc (2L * sizeof (double), "complex"));
2464 SCM_SETCAR (z
, scm_tc_dblc
);
2481 if (0 == scm_bigcomp (x
, y
))
2495 if (SCM_REALPART (x
) != SCM_REALPART (y
))
2497 if (!(SCM_CPLXP (x
) && (SCM_IMAG (x
) != SCM_IMAG (y
))))
2506 SCM_PROC (s_number_p
, "number?", 1, 0, 0, scm_number_p
);
2507 SCM_PROC (s_complex_p
, "complex?", 1, 0, 0, scm_number_p
);
2516 if (SCM_NIMP (x
) && SCM_NUMP (x
))
2520 if (SCM_NIMP (x
) && SCM_NUMP (x
))
2530 SCM_PROC (s_real_p
, "real?", 1, 0, 0, scm_real_p
);
2531 SCM_PROC (s_rational_p
, "rational?", 1, 0, 0, scm_real_p
);
2552 SCM_PROC (s_int_p
, "integer?", 1, 0, 0, scm_integer_p
);
2571 r
= SCM_REALPART (x
);
2579 #endif /* SCM_FLOATS */
2581 SCM_PROC (s_inexact_p
, "inexact?", 1, 0, 0, scm_inexact_p
);
2588 if (SCM_NIMP (x
) && SCM_INEXP (x
))
2597 SCM_PROC1 (s_eq_p
, "=", scm_tc7_rpsubr
, scm_num_eq_p
);
2609 #ifndef SCM_RECKLESS
2610 if (!(SCM_NIMP (x
)))
2613 scm_wta (x
, (char *) SCM_ARG1
, s_eq_p
);
2620 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2622 return (0 == scm_bigcomp (x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2623 SCM_ASRTGO (SCM_INEXP (y
), bady
);
2625 return ((SCM_REALP (y
) && (scm_big2dbl (x
) == SCM_REALPART (y
)))
2629 SCM_ASRTGO (SCM_INEXP (x
), badx
);
2631 SCM_ASSERT (SCM_NIMP (x
) && SCM_INEXP (x
), x
, SCM_ARG1
, s_eq_p
);
2641 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2649 SCM_ASRTGO (SCM_INEXP (y
), bady
);
2651 SCM_ASRTGO (SCM_NIMP (y
) && SCM_INEXP (y
), bady
);
2653 if (SCM_REALPART (x
) != SCM_REALPART (y
))
2656 return ((SCM_CPLXP (y
) && (SCM_IMAG (x
) == SCM_IMAG (y
)))
2659 return SCM_CPLXP (y
) ? SCM_BOOL_F
: SCM_BOOL_T
;
2664 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2667 #ifndef SCM_RECKLESS
2668 if (!(SCM_INEXP (y
)))
2671 scm_wta (y
, (char *) SCM_ARG2
, s_eq_p
);
2675 #ifndef SCM_RECKLESS
2676 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
2679 scm_wta (y
, (char *) SCM_ARG2
, s_eq_p
);
2684 return ((SCM_REALP (y
) && (((double) SCM_INUM (x
)) == SCM_REALPART (y
)))
2692 SCM_ASSERT (SCM_NIMP (x
) && SCM_BIGP (x
), x
, SCM_ARG1
, s_eq_p
);
2695 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
2696 return (0 == scm_bigcomp (x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2700 #ifndef SCM_RECKLESS
2701 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
2704 scm_wta (y
, (char *) SCM_ARG2
, s_eq_p
);
2710 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_eq_p
);
2711 SCM_ASSERT (SCM_INUMP (y
), y
, SCM_ARG2
, s_eq_p
);
2714 return ((long) x
== (long) y
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2719 SCM_PROC1 (s_less_p
, "<", scm_tc7_rpsubr
, scm_less_p
);
2730 #ifndef SCM_RECKLESS
2731 if (!(SCM_NIMP (x
)))
2734 scm_wta (x
, (char *) SCM_ARG1
, s_less_p
);
2740 return SCM_BIGSIGN (x
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2741 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2743 return (1 == scm_bigcomp (x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2744 SCM_ASRTGO (SCM_REALP (y
), bady
);
2745 return ((scm_big2dbl (x
) < SCM_REALPART (y
))
2749 SCM_ASRTGO (SCM_REALP (x
), badx
);
2751 SCM_ASSERT (SCM_NIMP (x
) && SCM_REALP (x
), x
, SCM_ARG1
, s_less_p
);
2754 return ((SCM_REALPART (x
) < ((double) SCM_INUM (y
)))
2758 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2760 return (SCM_REALPART (x
) < scm_big2dbl (y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2761 SCM_ASRTGO (SCM_REALP (y
), bady
);
2763 SCM_ASRTGO (SCM_NIMP (y
) && SCM_REALP (y
), bady
);
2765 return (SCM_REALPART (x
) < SCM_REALPART (y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2770 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2772 return SCM_BIGSIGN (y
) ? SCM_BOOL_F
: SCM_BOOL_T
;
2773 #ifndef SCM_RECKLESS
2774 if (!(SCM_REALP (y
)))
2777 scm_wta (y
, (char *) SCM_ARG2
, s_less_p
);
2781 #ifndef SCM_RECKLESS
2782 if (!(SCM_NIMP (y
) && SCM_REALP (y
)))
2785 scm_wta (y
, (char *) SCM_ARG2
, s_less_p
);
2789 return ((((double) SCM_INUM (x
)) < SCM_REALPART (y
))
2797 SCM_ASSERT (SCM_NIMP (x
) && SCM_BIGP (x
), x
, SCM_ARG1
, s_less_p
);
2799 return SCM_BIGSIGN (x
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2800 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
2801 return (1 == scm_bigcomp (x
, y
)) ? SCM_BOOL_T
: SCM_BOOL_F
;
2805 #ifndef SCM_RECKLESS
2806 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
2809 scm_wta (y
, (char *) SCM_ARG2
, s_less_p
);
2812 return SCM_BIGSIGN (y
) ? SCM_BOOL_F
: SCM_BOOL_T
;
2815 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_less_p
);
2816 SCM_ASSERT (SCM_INUMP (y
), y
, SCM_ARG2
, s_less_p
);
2819 return ((long) x
< (long) y
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2823 SCM_PROC1 (s_gr_p
, ">", scm_tc7_rpsubr
, scm_gr_p
);
2830 return scm_less_p (y
, x
);
2835 SCM_PROC1 (s_leq_p
, "<=", scm_tc7_rpsubr
, scm_leq_p
);
2842 return SCM_BOOL_NOT (scm_less_p (y
, x
));
2847 SCM_PROC1 (s_geq_p
, ">=", scm_tc7_rpsubr
, scm_geq_p
);
2854 return SCM_BOOL_NOT (scm_less_p (x
, y
));
2859 SCM_PROC (s_zero_p
, "zero?", 1, 0, 0, scm_zero_p
);
2869 SCM_ASRTGO (SCM_NIMP (z
), badz
);
2872 #ifndef SCM_RECKLESS
2873 if (!(SCM_INEXP (z
)))
2876 scm_wta (z
, (char *) SCM_ARG1
, s_zero_p
);
2880 SCM_ASSERT (SCM_NIMP (z
) && SCM_INEXP (z
), z
, SCM_ARG1
, s_zero_p
);
2882 return (z
== scm_flo0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2888 SCM_ASSERT (SCM_NIMP (z
) && SCM_BIGP (z
), z
, SCM_ARG1
, s_zero_p
);
2892 SCM_ASSERT (SCM_INUMP (z
), z
, SCM_ARG1
, s_zero_p
);
2895 return (z
== SCM_INUM0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2900 SCM_PROC (s_positive_p
, "positive?", 1, 0, 0, scm_positive_p
);
2910 SCM_ASRTGO (SCM_NIMP (x
), badx
);
2912 return SCM_TYP16 (x
) == scm_tc16_bigpos
? SCM_BOOL_T
: SCM_BOOL_F
;
2913 #ifndef SCM_RECKLESS
2914 if (!(SCM_REALP (x
)))
2917 scm_wta (x
, (char *) SCM_ARG1
, s_positive_p
);
2921 SCM_ASSERT (SCM_NIMP (x
) && SCM_REALP (x
), x
, SCM_ARG1
, s_positive_p
);
2923 return (SCM_REALPART (x
) > 0.0) ? SCM_BOOL_T
: SCM_BOOL_F
;
2929 SCM_ASSERT (SCM_NIMP (x
) && SCM_BIGP (x
), x
, SCM_ARG1
, s_positive_p
);
2930 return SCM_TYP16 (x
) == scm_tc16_bigpos
? SCM_BOOL_T
: SCM_BOOL_F
;
2933 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_positive_p
);
2936 return (x
> SCM_INUM0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2941 SCM_PROC (s_negative_p
, "negative?", 1, 0, 0, scm_negative_p
);
2951 SCM_ASRTGO (SCM_NIMP (x
), badx
);
2953 return SCM_TYP16 (x
) == scm_tc16_bigpos
? SCM_BOOL_F
: SCM_BOOL_T
;
2954 #ifndef SCM_RECKLESS
2955 if (!(SCM_REALP (x
)))
2958 scm_wta (x
, (char *) SCM_ARG1
, s_negative_p
);
2962 SCM_ASSERT (SCM_NIMP (x
) && SCM_REALP (x
), x
, SCM_ARG1
, s_negative_p
);
2964 return (SCM_REALPART (x
) < 0.0) ? SCM_BOOL_T
: SCM_BOOL_F
;
2970 SCM_ASSERT (SCM_NIMP (x
) && SCM_BIGP (x
), x
, SCM_ARG1
, s_negative_p
);
2971 return (SCM_TYP16 (x
) == scm_tc16_bigneg
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2974 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_negative_p
);
2977 return (x
< SCM_INUM0
) ? SCM_BOOL_T
: SCM_BOOL_F
;
2981 SCM_PROC1 (s_max
, "max", scm_tc7_asubr
, scm_max
);
2993 #ifndef SCM_RECKLESS
2994 if (!(SCM_NUMBERP (x
)))
2997 scm_wta (x
, (char *) SCM_ARG1
, s_max
);
3006 SCM_ASRTGO (SCM_NIMP (x
), badx
);
3010 return SCM_BIGSIGN (x
) ? y
: x
;
3011 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3013 return (1 == scm_bigcomp (x
, y
)) ? y
: x
;
3014 SCM_ASRTGO (SCM_REALP (y
), bady
);
3015 z
= scm_big2dbl (x
);
3016 return (z
< SCM_REALPART (y
)) ? y
: scm_makdbl (z
, 0.0);
3018 SCM_ASRTGO (SCM_REALP (x
), badx
);
3020 SCM_ASSERT (SCM_NIMP (x
) && SCM_REALP (x
), x
, SCM_ARG1
, s_max
);
3023 return ((SCM_REALPART (x
) < (z
= SCM_INUM (y
)))
3024 ? scm_makdbl (z
, 0.0)
3027 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3029 return ((SCM_REALPART (x
) < (z
= scm_big2dbl (y
)))
3030 ? scm_makdbl (z
, 0.0)
3032 SCM_ASRTGO (SCM_REALP (y
), bady
);
3034 SCM_ASRTGO (SCM_NIMP (y
) && SCM_REALP (y
), bady
);
3036 return (SCM_REALPART (x
) < SCM_REALPART (y
)) ? y
: x
;
3041 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3043 return SCM_BIGSIGN (y
) ? x
: y
;
3044 #ifndef SCM_RECKLESS
3045 if (!(SCM_REALP (y
)))
3048 scm_wta (y
, (char *) SCM_ARG2
, s_max
);
3052 #ifndef SCM_RECKLESS
3053 if (!(SCM_NIMP (y
) && SCM_REALP (y
)))
3056 scm_wta (y
, (char *) SCM_ARG2
, s_max
);
3060 return (((z
= SCM_INUM (x
)) < SCM_REALPART (y
))
3062 : scm_makdbl (z
, 0.0));
3068 SCM_ASSERT (SCM_NIMP (x
) && SCM_BIGP (x
), x
, SCM_ARG1
, s_max
);
3070 return SCM_BIGSIGN (x
) ? y
: x
;
3071 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3072 return (1 == scm_bigcomp (x
, y
)) ? y
: x
;
3076 #ifndef SCM_RECKLESS
3077 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3080 scm_wta (y
, (char *) SCM_ARG2
, s_max
);
3083 return SCM_BIGSIGN (y
) ? x
: y
;
3086 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_max
);
3087 SCM_ASSERT (SCM_INUMP (y
), y
, SCM_ARG2
, s_max
);
3090 return ((long) x
< (long) y
) ? y
: x
;
3096 SCM_PROC1 (s_min
, "min", scm_tc7_asubr
, scm_min
);
3108 #ifndef SCM_RECKLESS
3109 if (!(SCM_NUMBERP (x
)))
3112 scm_wta (x
, (char *) SCM_ARG1
, s_min
);
3121 SCM_ASRTGO (SCM_NIMP (x
), badx
);
3125 return SCM_BIGSIGN (x
) ? x
: y
;
3126 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3128 return (-1 == scm_bigcomp (x
, y
)) ? y
: x
;
3129 SCM_ASRTGO (SCM_REALP (y
), bady
);
3130 z
= scm_big2dbl (x
);
3131 return (z
> SCM_REALPART (y
)) ? y
: scm_makdbl (z
, 0.0);
3133 SCM_ASRTGO (SCM_REALP (x
), badx
);
3135 SCM_ASSERT (SCM_NIMP (x
) && SCM_REALP (x
), x
, SCM_ARG1
, s_min
);
3138 return ((SCM_REALPART (x
) > (z
= SCM_INUM (y
)))
3139 ? scm_makdbl (z
, 0.0)
3142 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3144 return ((SCM_REALPART (x
) > (z
= scm_big2dbl (y
)))
3145 ? scm_makdbl (z
, 0.0)
3147 SCM_ASRTGO (SCM_REALP (y
), bady
);
3149 SCM_ASRTGO (SCM_NIMP (y
) && SCM_REALP (y
), bady
);
3151 return (SCM_REALPART (x
) > SCM_REALPART (y
)) ? y
: x
;
3156 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3158 return SCM_BIGSIGN (y
) ? y
: x
;
3159 #ifndef SCM_RECKLESS
3160 if (!(SCM_REALP (y
)))
3163 scm_wta (y
, (char *) SCM_ARG2
, s_min
);
3167 #ifndef SCM_RECKLESS
3168 if (!(SCM_NIMP (y
) && SCM_REALP (y
)))
3171 scm_wta (y
, (char *) SCM_ARG2
, s_min
);
3175 return (((z
= SCM_INUM (x
)) > SCM_REALPART (y
))
3177 : scm_makdbl (z
, 0.0));
3183 SCM_ASSERT (SCM_NIMP (x
) && SCM_BIGP (x
), x
, SCM_ARG1
, s_min
);
3185 return SCM_BIGSIGN (x
) ? x
: y
;
3186 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3187 return (-1 == scm_bigcomp (x
, y
)) ? y
: x
;
3191 #ifndef SCM_RECKLESS
3192 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3195 scm_wta (y
, (char *) SCM_ARG2
, s_min
);
3198 return SCM_BIGSIGN (y
) ? y
: x
;
3201 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_min
);
3202 SCM_ASSERT (SCM_INUMP (y
), y
, SCM_ARG2
, s_min
);
3205 return ((long) x
> (long) y
) ? y
: x
;
3211 SCM_PROC1 (s_sum
, "+", scm_tc7_asubr
, scm_sum
);
3222 #ifndef SCM_RECKLESS
3223 if (!(SCM_NUMBERP (x
)))
3226 scm_wta (x
, (char *) SCM_ARG1
, s_sum
);
3236 SCM_ASRTGO (SCM_NIMP (x
), badx
);
3246 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3249 if (SCM_NUMDIGS (x
) > SCM_NUMDIGS (y
))
3255 return scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3259 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3261 return scm_makdbl (scm_big2dbl (x
) + SCM_REALPART (y
),
3262 SCM_CPLXP (y
) ? SCM_IMAG (y
) : 0.0);
3264 SCM_ASRTGO (SCM_INEXP (x
), badx
);
3266 SCM_ASRTGO (SCM_NIMP (x
) && SCM_INEXP (x
), badx
);
3276 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3284 #ifndef SCM_RECKLESS
3285 else if (!(SCM_INEXP (y
)))
3288 scm_wta (y
, (char *) SCM_ARG2
, s_sum
);
3292 #ifndef SCM_RECKLESS
3293 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
3296 scm_wta (y
, (char *) SCM_ARG2
, s_sum
);
3306 return scm_makdbl (SCM_REALPART (x
) + SCM_REALPART (y
), i
);
3312 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3317 #ifndef SCM_DIGSTOOBIG
3318 long z
= scm_pseudolong (SCM_INUM (x
));
3319 return scm_addbig ((SCM_BIGDIG
*) & z
,
3321 (x
< 0) ? 0x0100 : 0,
3324 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3325 scm_longdigs (SCM_INUM (x
), zdigs
);
3326 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3331 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3333 SCM_ASRTGO (SCM_NIMP (y
) && SCM_INEXP (y
), bady
);
3336 return scm_makdbl (SCM_INUM (x
) + SCM_REALPART (y
),
3337 SCM_CPLXP (y
) ? SCM_IMAG (y
) : 0.0);
3344 SCM_ASRTGO (SCM_NIMP (x
) && SCM_BIGP (x
), badx
);
3352 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3353 if (SCM_NUMDIGS (x
) > SCM_NUMDIGS (y
))
3359 return scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
), SCM_BIGSIGN (x
),
3364 #ifndef SCM_RECKLESS
3365 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3368 scm_wta (y
, (char *) SCM_ARG2
, s_sum
);
3373 #ifndef SCM_DIGSTOOBIG
3374 long z
= scm_pseudolong (SCM_INUM (x
));
3375 return scm_addbig (&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
3377 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3378 scm_longdigs (SCM_INUM (x
), zdigs
);
3379 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
3384 SCM_ASRTGO (SCM_INUMP (x
), badx
);
3385 SCM_ASSERT (SCM_INUMP (y
), y
, SCM_ARG2
, s_sum
);
3388 x
= SCM_INUM (x
) + SCM_INUM (y
);
3389 if (SCM_FIXABLE (x
))
3390 return SCM_MAKINUM (x
);
3392 return scm_long2big (x
);
3395 return scm_makdbl ((double) x
, 0.0);
3397 scm_num_overflow (s_sum
);
3398 return SCM_UNSPECIFIED
;
3406 SCM_PROC1 (s_difference
, "-", scm_tc7_asubr
, scm_difference
);
3409 scm_difference (x
, y
)
3416 #ifndef SCM_RECKLESS
3417 if (!(SCM_NIMP (x
)))
3420 scm_wta (x
, (char *) SCM_ARG1
, s_difference
);
3428 x
= scm_copybig (x
, !SCM_BIGSIGN (x
));
3429 return (SCM_NUMDIGS (x
) * SCM_BITSPERDIG
/ SCM_CHAR_BIT
3431 ? scm_big2inum (x
, SCM_NUMDIGS (x
))
3435 SCM_ASRTGO (SCM_INEXP (x
), badx
);
3436 return scm_makdbl (- SCM_REALPART (x
),
3437 SCM_CPLXP (x
) ? -SCM_IMAG (x
) : 0.0);
3440 return scm_sum (x
, SCM_MAKINUM (- SCM_INUM (y
)));
3442 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3446 return ((SCM_NUMDIGS (x
) < SCM_NUMDIGS (y
))
3447 ? scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3450 : scm_addbig (SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3451 SCM_BIGSIGN (y
) ^ 0x0100,
3453 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3454 return scm_makdbl (scm_big2dbl (x
) - SCM_REALPART (y
),
3455 SCM_CPLXP (y
) ? -SCM_IMAG (y
) : 0.0);
3457 SCM_ASRTGO (SCM_INEXP (x
), badx
);
3459 return scm_makdbl (SCM_REALPART (x
) - scm_big2dbl (y
),
3460 SCM_CPLXP (x
) ? SCM_IMAG (x
) : 0.0);
3461 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3463 SCM_ASRTGO (SCM_INEXP (x
), badx
);
3464 SCM_ASRTGO (SCM_NIMP (y
) && SCM_INEXP (y
), bady
);
3469 return scm_makdbl (SCM_REAL (x
) - SCM_REAL (y
),
3470 SCM_IMAG (x
) - SCM_IMAG (y
));
3472 return scm_makdbl (SCM_REAL (x
) - SCM_REALPART (y
), SCM_IMAG (x
));
3474 return scm_makdbl (SCM_REALPART (x
) - SCM_REALPART (y
),
3475 SCM_CPLXP (y
) ? - SCM_IMAG (y
) : 0.0);
3485 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3488 #ifndef SCM_DIGSTOOBIG
3489 long z
= scm_pseudolong (SCM_INUM (x
));
3490 return scm_addbig ((SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3491 (x
< 0) ? 0x0100 : 0,
3494 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3495 scm_longdigs (SCM_INUM (x
), zdigs
);
3496 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3500 #ifndef SCM_RECKLESS
3501 if (!(SCM_INEXP (y
)))
3504 scm_wta (y
, (char *) SCM_ARG2
, s_difference
);
3508 #ifndef SCM_RECKLESS
3509 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
3512 scm_wta (y
, (char *) SCM_ARG2
, s_difference
);
3516 return scm_makdbl (SCM_INUM (x
) - SCM_REALPART (y
),
3517 SCM_CPLXP (y
) ? -SCM_IMAG (y
) : 0.0);
3523 SCM_ASSERT (SCM_NIMP (x
) && SCM_BIGP (x
), x
, SCM_ARG1
, s_difference
);
3526 x
= scm_copybig (x
, !SCM_BIGSIGN (x
));
3527 return (SCM_NUMDIGS (x
) * SCM_BITSPERDIG
/ SCM_CHAR_BIT
3529 ? scm_big2inum (x
, SCM_NUMDIGS (x
))
3534 #ifndef SCM_DIGSTOOBIG
3535 long z
= scm_pseudolong (SCM_INUM (y
));
3536 return scm_addbig (&z
, SCM_DIGSPERLONG
, (y
< 0) ? 0 : 0x0100, x
, 0);
3538 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3539 scm_longdigs (SCM_INUM (x
), zdigs
);
3540 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (y
< 0) ? 0 : 0x0100,
3544 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3545 return (SCM_NUMDIGS (x
) < SCM_NUMDIGS (y
)) ?
3546 scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
), SCM_BIGSIGN (x
),
3548 scm_addbig (SCM_BDIGITS (y
), SCM_NUMDIGS (y
), SCM_BIGSIGN (y
) ^ 0x0100,
3558 #ifndef SCM_RECKLESS
3559 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3562 scm_wta (y
, (char *) SCM_ARG2
, s_difference
);
3566 #ifndef SCM_DIGSTOOBIG
3567 long z
= scm_pseudolong (SCM_INUM (x
));
3568 return scm_addbig (&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3571 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3572 scm_longdigs (SCM_INUM (x
), zdigs
);
3573 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3579 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_difference
);
3585 SCM_ASSERT (SCM_INUMP (y
), y
, SCM_ARG2
, s_difference
);
3588 x
= SCM_INUM (x
) - SCM_INUM (y
);
3590 if (SCM_FIXABLE (x
))
3591 return SCM_MAKINUM (x
);
3593 return scm_long2big (x
);
3596 return scm_makdbl ((double) x
, 0.0);
3598 scm_num_overflow (s_difference
);
3599 return SCM_UNSPECIFIED
;
3607 SCM_PROC1 (s_product
, "*", scm_tc7_asubr
, scm_product
);
3617 return SCM_MAKINUM (1L);
3618 #ifndef SCM_RECKLESS
3619 if (!(SCM_NUMBERP (x
)))
3622 scm_wta (x
, (char *) SCM_ARG1
, s_product
);
3632 SCM_ASRTGO (SCM_NIMP (x
), badx
);
3642 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3644 return scm_mulbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3645 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3646 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
));
3647 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3650 double bg
= scm_big2dbl (x
);
3651 return scm_makdbl (bg
* SCM_REALPART (y
),
3652 SCM_CPLXP (y
) ? bg
* SCM_IMAG (y
) : 0.0);
3655 SCM_ASRTGO (SCM_INEXP (x
), badx
);
3657 SCM_ASRTGO (SCM_NIMP (x
) && SCM_INEXP (x
), badx
);
3667 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3675 #ifndef SCM_RECKLESS
3676 else if (!(SCM_INEXP (y
)))
3679 scm_wta (y
, (char *) SCM_ARG2
, s_product
);
3683 #ifndef SCM_RECKLESS
3684 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
3687 scm_wta (y
, (char *) SCM_ARG2
, s_product
);
3694 return scm_makdbl (SCM_REAL (x
) * SCM_REAL (y
)
3695 - SCM_IMAG (x
) * SCM_IMAG (y
),
3696 SCM_REAL (x
) * SCM_IMAG (y
)
3697 + SCM_IMAG (x
) * SCM_REAL (y
));
3699 return scm_makdbl (SCM_REAL (x
) * SCM_REALPART (y
),
3700 SCM_IMAG (x
) * SCM_REALPART (y
));
3702 return scm_makdbl (SCM_REALPART (x
) * SCM_REALPART (y
),
3704 ? SCM_REALPART (x
) * SCM_IMAG (y
)
3710 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3716 if (SCM_MAKINUM (1L) == x
)
3719 #ifndef SCM_DIGSTOOBIG
3720 long z
= scm_pseudolong (SCM_INUM (x
));
3721 return scm_mulbig ((SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3722 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3723 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3725 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3726 scm_longdigs (SCM_INUM (x
), zdigs
);
3727 return scm_mulbig (zdigs
, SCM_DIGSPERLONG
,
3728 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3729 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3733 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3735 SCM_ASRTGO (SCM_NIMP (y
) && SCM_INEXP (y
), bady
);
3738 return scm_makdbl (SCM_INUM (x
) * SCM_REALPART (y
),
3739 SCM_CPLXP (y
) ? SCM_INUM (x
) * SCM_IMAG (y
) : 0.0);
3745 SCM_ASRTGO (SCM_NIMP (x
) && SCM_BIGP (x
), badx
);
3753 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
3754 return scm_mulbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3755 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3756 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
));
3760 #ifndef SCM_RECKLESS
3761 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
3764 scm_wta (y
, (char *) SCM_ARG2
, s_product
);
3770 if (SCM_MAKINUM (1L) == x
)
3773 #ifndef SCM_DIGSTOOBIG
3774 long z
= scm_pseudolong (SCM_INUM (x
));
3775 return scm_mulbig (&z
, SCM_DIGSPERLONG
,
3776 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3777 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3779 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3780 scm_longdigs (SCM_INUM (x
), zdigs
);
3781 return scm_mulbig (zdigs
, SCM_DIGSPERLONG
,
3782 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3783 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3788 SCM_ASRTGO (SCM_INUMP (x
), badx
);
3789 SCM_ASSERT (SCM_INUMP (y
), y
, SCM_ARG2
, s_product
);
3799 y
= SCM_MAKINUM (k
);
3800 if (k
!= SCM_INUM (y
) || k
/ i
!= j
)
3803 int sgn
= (i
< 0) ^ (j
< 0);
3804 #ifndef SCM_DIGSTOOBIG
3805 i
= scm_pseudolong (i
);
3806 j
= scm_pseudolong (j
);
3807 return scm_mulbig ((SCM_BIGDIG
*) & i
, SCM_DIGSPERLONG
,
3808 (SCM_BIGDIG
*) & j
, SCM_DIGSPERLONG
, sgn
);
3809 #else /* SCM_DIGSTOOBIG */
3810 SCM_BIGDIG idigs
[SCM_DIGSPERLONG
];
3811 SCM_BIGDIG jdigs
[SCM_DIGSPERLONG
];
3812 scm_longdigs (i
, idigs
);
3813 scm_longdigs (j
, jdigs
);
3814 return scm_mulbig (idigs
, SCM_DIGSPERLONG
,
3815 jdigs
, SCM_DIGSPERLONG
,
3821 return scm_makdbl (((double) i
) * ((double) j
), 0.0);
3823 scm_num_overflow (s_product
);
3833 scm_num2dbl (a
, why
)
3838 return (double) SCM_INUM (a
);
3840 SCM_ASSERT (SCM_NIMP (a
), a
, "wrong type argument", why
);
3842 return (SCM_REALPART (a
));
3845 return scm_big2dbl (a
);
3847 SCM_ASSERT (0, a
, "wrong type argument", why
);
3848 return SCM_UNSPECIFIED
;
3852 SCM_PROC1 (s_divide
, "/", scm_tc7_asubr
, scm_divide
);
3863 #ifndef SCM_RECKLESS
3864 if (!(SCM_NIMP (x
)))
3867 scm_wta (x
, (char *) SCM_ARG1
, s_divide
);
3874 return scm_makdbl (1.0 / scm_big2dbl (x
), 0.0);
3876 SCM_ASRTGO (SCM_INEXP (x
), badx
);
3878 return scm_makdbl (1.0 / SCM_REALPART (x
), 0.0);
3882 return scm_makdbl (r
/ d
, -i
/ d
);
3891 #ifndef SCM_RECKLESS
3893 scm_num_overflow (s_divide
);
3901 SCM w
= scm_copybig (x
, SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0));
3902 return (scm_divbigdig (SCM_BDIGITS (w
), SCM_NUMDIGS (w
),
3904 ? scm_makdbl (scm_big2dbl (x
) / SCM_INUM (y
), 0.0)
3907 #ifndef SCM_DIGSTOOBIG
3908 z
= scm_pseudolong (z
);
3909 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3910 (SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3911 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
3914 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3915 scm_longdigs (z
, zdigs
);
3916 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3917 zdigs
, SCM_DIGSPERLONG
,
3918 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
3921 return z
? z
: scm_makdbl (scm_big2dbl (x
) / SCM_INUM (y
), 0.0);
3923 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3926 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3927 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3928 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
), 3);
3929 return z
? z
: scm_makdbl (scm_big2dbl (x
) / scm_big2dbl (y
),
3932 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3934 return scm_makdbl (scm_big2dbl (x
) / SCM_REALPART (y
), 0.0);
3935 a
= scm_big2dbl (x
);
3939 SCM_ASRTGO (SCM_INEXP (x
), badx
);
3946 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3949 d
= scm_big2dbl (y
);
3952 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3954 SCM_ASRTGO (SCM_NIMP (y
) && SCM_INEXP (y
), bady
);
3958 d
= SCM_REALPART (y
);
3960 return scm_makdbl (SCM_REALPART (x
) / d
,
3961 SCM_CPLXP (x
) ? SCM_IMAG (x
) / d
: 0.0);
3963 a
= SCM_REALPART (x
);
3969 return scm_makdbl ((a
* r
+ SCM_IMAG (x
) * i
) / d
,
3970 (SCM_IMAG (x
) * r
- a
* i
) / d
);
3974 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
3976 return scm_makdbl (1.0 / ((double) SCM_INUM (x
)), 0.0);
3981 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3983 return scm_makdbl (SCM_INUM (x
) / scm_big2dbl (y
), 0.0);
3984 #ifndef SCM_RECKLESS
3985 if (!(SCM_INEXP (y
)))
3988 scm_wta (y
, (char *) SCM_ARG2
, s_divide
);
3992 #ifndef SCM_RECKLESS
3993 if (!(SCM_NIMP (y
) && SCM_INEXP (y
)))
3996 scm_wta (y
, (char *) SCM_ARG2
, s_divide
);
4001 return scm_makdbl (SCM_INUM (x
) / SCM_REALPART (y
), 0.0);
4007 return scm_makdbl ((a
* r
) / d
, (-a
* i
) / d
);
4014 SCM_ASSERT (SCM_NIMP (x
) && SCM_BIGP (x
), x
, SCM_ARG1
, s_divide
);
4028 SCM w
= scm_copybig (x
, SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0));
4029 if (scm_divbigdig (SCM_BDIGITS (w
), SCM_NUMDIGS (w
),
4034 #ifndef SCM_DIGSTOOBIG
4035 z
= scm_pseudolong (z
);
4036 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
4037 &z
, SCM_DIGSPERLONG
,
4038 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
4041 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
4042 scm_longdigs (z
, zdigs
);
4043 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
4044 zdigs
, SCM_DIGSPERLONG
,
4045 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
4051 SCM_ASRTGO (SCM_NIMP (y
) && SCM_BIGP (y
), bady
);
4052 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
4053 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
4054 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
), 3);
4062 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
4068 #ifndef SCM_RECKLESS
4069 if (!(SCM_NIMP (y
) && SCM_BIGP (y
)))
4072 scm_wta (y
, (char *) SCM_ARG2
, s_divide
);
4078 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_divide
);
4081 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
4085 SCM_ASSERT (SCM_INUMP (y
), y
, SCM_ARG2
, s_divide
);
4089 long z
= SCM_INUM (y
);
4090 if ((0 == z
) || SCM_INUM (x
) % z
)
4092 z
= SCM_INUM (x
) / z
;
4093 if (SCM_FIXABLE (z
))
4094 return SCM_MAKINUM (z
);
4096 return scm_long2big (z
);
4100 return scm_makdbl (((double) SCM_INUM (x
)) / ((double) SCM_INUM (y
)), 0.0);
4103 scm_num_overflow (s_divide
);
4104 return SCM_UNSPECIFIED
;
4113 SCM_PROC1 (s_asinh
, "$asinh", scm_tc7_cxr
, (SCM (*)()) scm_asinh
);
4119 return log (x
+ sqrt (x
* x
+ 1));
4125 SCM_PROC1 (s_acosh
, "$acosh", scm_tc7_cxr
, (SCM (*)()) scm_acosh
);
4131 return log (x
+ sqrt (x
* x
- 1));
4137 SCM_PROC1 (s_atanh
, "$atanh", scm_tc7_cxr
, (SCM (*)()) scm_atanh
);
4143 return 0.5 * log ((1 + x
) / (1 - x
));
4149 SCM_PROC1 (s_truncate
, "truncate", scm_tc7_cxr
, (SCM (*)()) scm_truncate
);
4162 SCM_PROC1 (s_round
, "round", scm_tc7_cxr
, (SCM (*)()) scm_round
);
4168 double plus_half
= x
+ 0.5;
4169 double result
= floor (plus_half
);
4170 /* Adjust so that the scm_round is towards even. */
4171 return (plus_half
== result
&& plus_half
/ 2 != floor (plus_half
/ 2))
4172 ? result
- 1 : result
;
4177 SCM_PROC1 (s_exact_to_inexact
, "exact->inexact", scm_tc7_cxr
, (SCM (*)()) scm_exact_to_inexact
);
4180 scm_exact_to_inexact (z
)
4187 SCM_PROC1 (s_i_floor
, "floor", scm_tc7_cxr
, (SCM (*)()) floor
);
4188 SCM_PROC1 (s_i_ceil
, "ceiling", scm_tc7_cxr
, (SCM (*)()) ceil
);
4189 SCM_PROC1 (s_i_sqrt
, "$sqrt", scm_tc7_cxr
, (SCM (*)()) sqrt
);
4190 SCM_PROC1 (s_i_abs
, "$abs", scm_tc7_cxr
, (SCM (*)()) fabs
);
4191 SCM_PROC1 (s_i_exp
, "$exp", scm_tc7_cxr
, (SCM (*)()) exp
);
4192 SCM_PROC1 (s_i_log
, "$log", scm_tc7_cxr
, (SCM (*)()) log
);
4193 SCM_PROC1 (s_i_sin
, "$sin", scm_tc7_cxr
, (SCM (*)()) sin
);
4194 SCM_PROC1 (s_i_cos
, "$cos", scm_tc7_cxr
, (SCM (*)()) cos
);
4195 SCM_PROC1 (s_i_tan
, "$tan", scm_tc7_cxr
, (SCM (*)()) tan
);
4196 SCM_PROC1 (s_i_asin
, "$asin", scm_tc7_cxr
, (SCM (*)()) asin
);
4197 SCM_PROC1 (s_i_acos
, "$acos", scm_tc7_cxr
, (SCM (*)()) acos
);
4198 SCM_PROC1 (s_i_atan
, "$atan", scm_tc7_cxr
, (SCM (*)()) atan
);
4199 SCM_PROC1 (s_i_sinh
, "$sinh", scm_tc7_cxr
, (SCM (*)()) sinh
);
4200 SCM_PROC1 (s_i_cosh
, "$cosh", scm_tc7_cxr
, (SCM (*)()) cosh
);
4201 SCM_PROC1 (s_i_tanh
, "$tanh", scm_tc7_cxr
, (SCM (*)()) tanh
);
4208 static void scm_two_doubles
SCM_P ((SCM z1
,
4211 struct dpair
* xy
));
4214 scm_two_doubles (z1
, z2
, sstring
, xy
)
4220 xy
->x
= SCM_INUM (z1
);
4224 SCM_ASRTGO (SCM_NIMP (z1
), badz1
);
4226 xy
->x
= scm_big2dbl (z1
);
4229 #ifndef SCM_RECKLESS
4230 if (!(SCM_REALP (z1
)))
4231 badz1
:scm_wta (z1
, (char *) SCM_ARG1
, sstring
);
4233 xy
->x
= SCM_REALPART (z1
);
4237 SCM_ASSERT (SCM_NIMP (z1
) && SCM_REALP (z1
), z1
, SCM_ARG1
, sstring
);
4238 xy
->x
= SCM_REALPART (z1
);
4243 xy
->y
= SCM_INUM (z2
);
4247 SCM_ASRTGO (SCM_NIMP (z2
), badz2
);
4249 xy
->y
= scm_big2dbl (z2
);
4252 #ifndef SCM_RECKLESS
4253 if (!(SCM_REALP (z2
)))
4254 badz2
:scm_wta (z2
, (char *) SCM_ARG2
, sstring
);
4256 xy
->y
= SCM_REALPART (z2
);
4260 SCM_ASSERT (SCM_NIMP (z2
) && SCM_REALP (z2
), z2
, SCM_ARG2
, sstring
);
4261 xy
->y
= SCM_REALPART (z2
);
4270 SCM_PROC (s_sys_expt
, "$expt", 2, 0, 0, scm_sys_expt
);
4273 scm_sys_expt (z1
, z2
)
4278 scm_two_doubles (z1
, z2
, s_sys_expt
, &xy
);
4279 return scm_makdbl (pow (xy
.x
, xy
.y
), 0.0);
4284 SCM_PROC (s_sys_atan2
, "$atan2", 2, 0, 0, scm_sys_atan2
);
4287 scm_sys_atan2 (z1
, z2
)
4292 scm_two_doubles (z1
, z2
, s_sys_atan2
, &xy
);
4293 return scm_makdbl (atan2 (xy
.x
, xy
.y
), 0.0);
4298 SCM_PROC (s_make_rectangular
, "make-rectangular", 2, 0, 0, scm_make_rectangular
);
4301 scm_make_rectangular (z1
, z2
)
4306 scm_two_doubles (z1
, z2
, s_make_rectangular
, &xy
);
4307 return scm_makdbl (xy
.x
, xy
.y
);
4312 SCM_PROC (s_make_polar
, "make-polar", 2, 0, 0, scm_make_polar
);
4315 scm_make_polar (z1
, z2
)
4320 scm_two_doubles (z1
, z2
, s_make_polar
, &xy
);
4321 return scm_makdbl (xy
.x
* cos (xy
.y
), xy
.x
* sin (xy
.y
));
4327 SCM_PROC (s_real_part
, "real-part", 1, 0, 0, scm_real_part
);
4336 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4339 #ifndef SCM_RECKLESS
4340 if (!(SCM_INEXP (z
)))
4343 scm_wta (z
, (char *) SCM_ARG1
, s_real_part
);
4347 SCM_ASSERT (SCM_NIMP (z
) && SCM_INEXP (z
), z
, SCM_ARG1
, s_real_part
);
4350 return scm_makdbl (SCM_REAL (z
), 0.0);
4357 SCM_PROC (s_imag_part
, "imag-part", 1, 0, 0, scm_imag_part
);
4366 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4369 #ifndef SCM_RECKLESS
4370 if (!(SCM_INEXP (z
)))
4373 scm_wta (z
, (char *) SCM_ARG1
, s_imag_part
);
4377 SCM_ASSERT (SCM_NIMP (z
) && SCM_INEXP (z
), z
, SCM_ARG1
, s_imag_part
);
4380 return scm_makdbl (SCM_IMAG (z
), 0.0);
4386 SCM_PROC (s_magnitude
, "magnitude", 1, 0, 0, scm_magnitude
);
4395 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4398 #ifndef SCM_RECKLESS
4399 if (!(SCM_INEXP (z
)))
4402 scm_wta (z
, (char *) SCM_ARG1
, s_magnitude
);
4406 SCM_ASSERT (SCM_NIMP (z
) && SCM_INEXP (z
), z
, SCM_ARG1
, s_magnitude
);
4410 double i
= SCM_IMAG (z
), r
= SCM_REAL (z
);
4411 return scm_makdbl (sqrt (i
* i
+ r
* r
), 0.0);
4413 return scm_makdbl (fabs (SCM_REALPART (z
)), 0.0);
4419 SCM_PROC (s_angle
, "angle", 1, 0, 0, scm_angle
);
4428 x
= (z
>= SCM_INUM0
) ? 1.0 : -1.0;
4432 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4435 x
= (SCM_TYP16 (z
) == scm_tc16_bigpos
) ? 1.0 : -1.0;
4438 #ifndef SCM_RECKLESS
4439 if (!(SCM_INEXP (z
)))
4442 scm_wta (z
, (char *) SCM_ARG1
, s_angle
);
4446 SCM_ASSERT (SCM_NIMP (z
) && SCM_INEXP (z
), z
, SCM_ARG1
, s_angle
);
4450 x
= SCM_REALPART (z
);
4456 return scm_makdbl (atan2 (y
, x
), 0.0);
4460 SCM_PROC (s_inexact_to_exact
, "inexact->exact", 1, 0, 0, scm_inexact_to_exact
);
4463 scm_inexact_to_exact (z
)
4469 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4472 #ifndef SCM_RECKLESS
4473 if (!(SCM_REALP (z
)))
4476 scm_wta (z
, (char *) SCM_ARG1
, s_inexact_to_exact
);
4480 SCM_ASSERT (SCM_NIMP (z
) && SCM_REALP (z
), z
, SCM_ARG1
, s_inexact_to_exact
);
4484 double u
= floor (SCM_REALPART (z
) + 0.5);
4485 if ((u
<= SCM_MOST_POSITIVE_FIXNUM
) && (-u
<= -SCM_MOST_NEGATIVE_FIXNUM
))
4487 /* Negation is a workaround for HP700 cc bug */
4488 SCM ans
= SCM_MAKINUM ((long) u
);
4489 if (SCM_INUM (ans
) == (long) u
)
4492 SCM_ASRTGO (!IS_INF (u
), badz
); /* problem? */
4493 return scm_dbl2big (u
);
4496 return SCM_MAKINUM ((long) floor (SCM_REALPART (z
) + 0.5));
4502 #else /* ~SCM_FLOATS */
4503 SCM_PROC (s_trunc
, "truncate", 1, 0, 0, scm_trunc
);
4509 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_truncate
);
4515 #endif /* SCM_FLOATS */
4519 /* d must be integer */
4529 double u
= (d
< 0) ? -d
: d
;
4530 while (0 != floor (u
))
4535 ans
= scm_mkbig (i
, d
< 0);
4536 digits
= SCM_BDIGITS (ans
);
4544 #ifndef SCM_RECKLESS
4546 scm_num_overflow ("dbl2big");
4558 scm_sizet i
= SCM_NUMDIGS (b
);
4559 SCM_BIGDIG
*digits
= SCM_BDIGITS (b
);
4561 ans
= digits
[i
] + SCM_BIGRAD
* ans
;
4562 if (scm_tc16_bigneg
== SCM_TYP16 (b
))
4574 if (!SCM_FIXABLE (sl
))
4577 return scm_long2big (sl
);
4580 return scm_makdbl ((double) sl
, 0.0);
4586 return SCM_MAKINUM (sl
);
4593 scm_long_long2num (sl
)
4596 if (!SCM_FIXABLE (sl
))
4599 return scm_long_long2big (sl
);
4602 return scm_makdbl ((double) sl
, 0.0);
4608 return SCM_MAKINUM (sl
);
4618 if (!SCM_POSFIXABLE (sl
))
4621 return scm_ulong2big (sl
);
4624 return scm_makdbl ((double) sl
, 0.0);
4630 return SCM_MAKINUM (sl
);
4635 scm_num2long (num
, pos
, s_caller
)
4641 if (SCM_INUMP (num
))
4643 res
= SCM_INUM (num
);
4646 SCM_ASRTGO (SCM_NIMP (num
), errout
);
4648 if (SCM_REALP (num
))
4650 double u
= SCM_REALPART (num
);
4652 if ((double) res
== u
)
4665 for (l
= SCM_NUMDIGS (num
); l
--;)
4667 res
= SCM_BIGUP (res
) + SCM_BDIGITS (num
)[l
];
4672 if (SCM_TYP16 (num
) == scm_tc16_bigpos
)
4679 scm_wta (num
, pos
, s_caller
);
4680 return SCM_UNSPECIFIED
;
4688 scm_num2long_long (num
, pos
, s_caller
)
4694 if (SCM_INUMP (num
))
4696 res
= SCM_INUM ((long_long
) num
);
4699 SCM_ASRTGO (SCM_NIMP (num
), errout
);
4701 if (SCM_REALP (num
))
4703 double u
= SCM_REALPART (num
);
4704 if (((SCM_MOST_NEGATIVE_FIXNUM
* 4) <= u
)
4705 && (u
<= (SCM_MOST_POSITIVE_FIXNUM
* 4 + 3)))
4715 scm_sizet l
= SCM_NUMDIGS (num
);
4716 SCM_ASRTGO (SCM_DIGSPERLONGLONG
>= l
, errout
);
4719 res
= SCM_LONGLONGBIGUP (res
) + SCM_BDIGITS (num
)[l
];
4724 scm_wta (num
, pos
, s_caller
);
4725 return SCM_UNSPECIFIED
;
4732 scm_num2ulong (num
, pos
, s_caller
)
4738 if (SCM_INUMP (num
))
4740 res
= SCM_INUM ((unsigned long) num
);
4743 SCM_ASRTGO (SCM_NIMP (num
), errout
);
4745 if (SCM_REALP (num
))
4747 double u
= SCM_REALPART (num
);
4748 if ((0 <= u
) && (u
<= (unsigned long) ~0L))
4758 unsigned long oldres
;
4762 for (l
= SCM_NUMDIGS (num
); l
--;)
4764 res
= SCM_BIGUP (res
) + SCM_BDIGITS (num
)[l
];
4773 scm_wta (num
, pos
, s_caller
);
4774 return SCM_UNSPECIFIED
;
4780 static void add1
SCM_P ((double f
, double *fsum
));
4796 SCM_NEWCELL (scm_flo0
);
4798 SCM_SETCAR (scm_flo0
, scm_tc_flo
);
4799 SCM_FLO (scm_flo0
) = 0.0;
4801 SCM_SETCDR (scm_flo0
, (SCM
) scm_must_malloc (1L * sizeof (double), "real"));
4802 SCM_REAL (scm_flo0
) = 0.0;
4803 SCM_SETCAR (scm_flo0
, scm_tc_dblr
);
4806 scm_dblprec
= (DBL_DIG
> 20) ? 20 : DBL_DIG
;
4808 { /* determine floating point precision */
4810 double fsum
= 1.0 + f
;
4814 if (++scm_dblprec
> 20)
4818 scm_dblprec
= scm_dblprec
- 1;
4820 #endif /* DBL_DIG */
4822 #include "numbers.x"