1 /* Copyright (C) 1995,1996,1997,1998, 1999 Free Software Foundation, Inc.
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
40 * If you do not wish that, delete this exception notice. */
42 /* Software engineering face-lift by Greg J. Badros, 11-Dec-1999,
43 gjb@cs.washington.edu, http://www.cs.washington.edu/homes/gjb */
55 #include "scm_validate.h"
58 #define DIGITS '0':case '1':case '2':case '3':case '4':\
59 case '5':case '6':case '7':case '8':case '9'
62 /* IS_INF tests its floating point number for infiniteness
65 #define IS_INF(x) ((x) == (x) / 2)
68 /* Return true if X is not infinite and is not a NaN
71 #define isfinite(x) (!IS_INF (x) && (x) == (x))
74 /* MAXEXP is the maximum double precision expontent
75 * FLTMAX is less than or scm_equal the largest single precision float
82 #endif /* ndef GO32 */
83 #endif /* def STDC_HEADERS */
85 #define MAXEXP DBL_MAX_10_EXP
87 #define MAXEXP 308 /* IEEE doubles */
88 #endif /* def DBL_MAX_10_EXP */
90 #define FLTMAX FLT_MAX
93 #endif /* def FLT_MAX */
94 #endif /* def SCM_FLOATS */
98 SCM_DEFINE (scm_exact_p
, "exact?", 1, 0, 0,
101 #define FUNC_NAME s_scm_exact_p
113 SCM_DEFINE (scm_odd_p
, "odd?", 1, 0, 0,
116 #define FUNC_NAME s_scm_odd_p
121 SCM_VALIDATE_BIGINT (1,n
);
122 return SCM_BOOL(1 & SCM_BDIGITS (n
)[0]);
125 SCM_VALIDATE_INUM (1,n
);
127 return SCM_BOOL(4 & (int) n
);
131 SCM_DEFINE (scm_even_p
, "even?", 1, 0, 0,
134 #define FUNC_NAME s_scm_even_p
139 SCM_VALIDATE_BIGINT (1,n
);
140 return SCM_NEGATE_BOOL(1 & SCM_BDIGITS (n
)[0]);
143 SCM_VALIDATE_INUM (1,n
);
145 return SCM_NEGATE_BOOL(4 & (int) n
);
149 SCM_GPROC (s_abs
, "abs", 1, 0, 0, scm_abs
, g_abs
);
157 SCM_GASSERT1 (SCM_BIGP (x
), g_abs
, x
, SCM_ARG1
, s_abs
);
158 if (SCM_TYP16 (x
) == scm_tc16_bigpos
)
160 return scm_copybig (x
, 0);
163 SCM_GASSERT1 (SCM_INUMP (x
), g_abs
, x
, SCM_ARG1
, s_abs
);
165 if (SCM_INUM (x
) >= 0)
168 if (!SCM_POSFIXABLE (x
))
170 return scm_long2big (x
);
172 scm_num_overflow (s_abs
);
174 return SCM_MAKINUM (x
);
177 SCM_GPROC (s_quotient
, "quotient", 2, 0, 0, scm_quotient
, g_quotient
);
180 scm_quotient (SCM x
, SCM y
)
187 SCM_GASSERT2 (SCM_BIGP (x
),
188 g_quotient
, x
, y
, SCM_ARG1
, s_quotient
);
191 SCM_ASRTGO (SCM_BIGP (y
), bady
);
192 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
193 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
194 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
), 2);
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
),
211 (SCM_BIGDIG
*) & w
, SCM_DIGSPERLONG
,
212 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 2);
215 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
216 scm_longdigs (z
, zdigs
);
217 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
218 zdigs
, SCM_DIGSPERLONG
,
219 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 2);
228 SCM_WTA_DISPATCH_2 (g_quotient
, x
, y
, SCM_ARG2
, s_quotient
);
233 SCM_GASSERT2 (SCM_INUMP (x
), g_quotient
, x
, y
, SCM_ARG1
, s_quotient
);
234 SCM_GASSERT2 (SCM_INUMP (y
), g_quotient
, x
, y
, SCM_ARG2
, s_quotient
);
236 if ((z
= SCM_INUM (y
)) == 0)
239 scm_num_overflow (s_quotient
);
241 z
= SCM_INUM (x
) / z
;
244 #if (__TURBOC__ == 1)
245 long t
= ((y
< 0) ? -SCM_INUM (x
) : SCM_INUM (x
)) % SCM_INUM (y
);
247 long t
= SCM_INUM (x
) % SCM_INUM (y
);
258 if (!SCM_FIXABLE (z
))
260 return scm_long2big (z
);
262 scm_num_overflow (s_quotient
);
264 return SCM_MAKINUM (z
);
267 SCM_GPROC (s_remainder
, "remainder", 2, 0, 0, scm_remainder
, g_remainder
);
270 scm_remainder (SCM x
, SCM y
)
276 SCM_GASSERT2 (SCM_BIGP (x
),
277 g_remainder
, x
, y
, SCM_ARG1
, s_remainder
);
280 SCM_ASRTGO (SCM_BIGP (y
), bady
);
281 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
282 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
285 if (!(z
= SCM_INUM (y
)))
287 return scm_divbigint (x
, z
, SCM_BIGSIGN (x
), 0);
294 SCM_WTA_DISPATCH_2 (g_remainder
, x
, y
, SCM_ARG2
, s_remainder
);
299 SCM_GASSERT2 (SCM_INUMP (x
), g_remainder
, x
, y
, SCM_ARG1
, s_remainder
);
300 SCM_GASSERT2 (SCM_INUMP (y
), g_remainder
, x
, y
, SCM_ARG2
, s_remainder
);
302 if (!(z
= SCM_INUM (y
)))
305 scm_num_overflow (s_remainder
);
307 #if (__TURBOC__ == 1)
311 z
= SCM_INUM (x
) % z
;
321 return SCM_MAKINUM (z
);
324 SCM_GPROC (s_modulo
, "modulo", 2, 0, 0, scm_modulo
, g_modulo
);
327 scm_modulo (SCM x
, SCM y
)
333 SCM_GASSERT2 (SCM_BIGP (x
),
334 g_modulo
, x
, y
, SCM_ARG1
, s_modulo
);
337 SCM_ASRTGO (SCM_BIGP (y
), bady
);
338 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
339 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
341 (SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
)) ? 1 : 0);
343 if (!(z
= SCM_INUM (y
)))
345 return scm_divbigint (x
, z
, y
< 0,
346 (SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0)) ? 1 : 0);
353 SCM_WTA_DISPATCH_2 (g_modulo
, x
, y
, SCM_ARG2
, s_modulo
);
355 return (SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0)) ? scm_sum (x
, y
) : x
;
358 SCM_GASSERT1 (SCM_INUMP (x
), g_modulo
, x
, y
, SCM_ARG1
, s_modulo
);
359 SCM_GASSERT2 (SCM_INUMP (y
), g_modulo
, x
, y
, SCM_ARG2
, s_modulo
);
361 if (!(yy
= SCM_INUM (y
)))
364 scm_num_overflow (s_modulo
);
368 z
= ((yy
< 0) ? -z
: z
) % yy
;
370 z
= SCM_INUM (x
) % yy
;
372 return SCM_MAKINUM (((yy
< 0) ? (z
> 0) : (z
< 0)) ? z
+ yy
: z
);
375 SCM_GPROC1 (s_gcd
, "gcd", scm_tc7_asubr
, scm_gcd
, g_gcd
);
378 scm_gcd (SCM x
, SCM y
)
380 register long u
, v
, k
, t
;
382 return SCM_UNBNDP (x
) ? SCM_INUM0
: x
;
388 SCM_GASSERT2 (SCM_BIGP (x
),
389 g_gcd
, x
, y
, SCM_ARG1
, s_gcd
);
391 x
= scm_copybig (x
, 0);
395 SCM_GASSERT2 (SCM_BIGP (y
),
396 g_gcd
, x
, y
, SCM_ARGn
, s_gcd
);
398 y
= scm_copybig (y
, 0);
399 switch (scm_bigcomp (x
, y
))
403 t
= scm_remainder (x
, y
);
410 y
= scm_remainder (y
, x
);
413 /* instead of the switch, we could just
414 return scm_gcd (y, scm_modulo (x, y)); */
428 SCM_GASSERT2 (SCM_INUMP (x
), g_gcd
, x
, y
, SCM_ARG1
, s_gcd
);
429 SCM_GASSERT2 (SCM_INUMP (y
), g_gcd
, x
, y
, SCM_ARGn
, s_gcd
);
444 for (k
= 1; !(1 & ((int) u
| (int) v
)); k
<<= 1, u
>>= 1, v
>>= 1);
463 if (!SCM_POSFIXABLE (u
))
465 return scm_long2big (u
);
467 scm_num_overflow (s_gcd
);
469 return SCM_MAKINUM (u
);
472 SCM_GPROC1 (s_lcm
, "lcm", scm_tc7_asubr
, scm_lcm
, g_lcm
);
475 scm_lcm (SCM n1
, SCM n2
)
479 SCM_GASSERT2 (SCM_INUMP (n1
) || SCM_UNBNDP (n1
),
480 g_lcm
, n1
, n2
, SCM_ARG1
, s_lcm
);
481 SCM_GASSERT2 (SCM_INUMP (n2
) || SCM_UNBNDP (n2
),
482 g_lcm
, n1
, n2
, SCM_ARGn
, s_lcm
);
484 SCM_GASSERT2 (SCM_INUMP (n1
)
487 g_lcm
, n1
, n2
, SCM_ARG1
, s_lcm
);
488 SCM_GASSERT2 (SCM_INUMP (n2
)
491 g_lcm
, n1
, n2
, SCM_ARGn
, s_lcm
);
495 n2
= SCM_MAKINUM (1L);
500 d
= scm_gcd (n1
, n2
);
503 return scm_abs (scm_product (n1
, scm_quotient (n2
, d
)));
508 #define scm_long2num SCM_MAKINUM
513 #define SCM_LOGOP_RETURN(x) scm_ulong2num(x)
515 #define SCM_LOGOP_RETURN(x) SCM_MAKINUM(x)
518 SCM_DEFINE1 (scm_logand
, "logand", scm_tc7_asubr
,
520 "Returns the integer which is the bit-wise AND of the two integer\n"
524 "(number->string (logand #b1100 #b1010) 2)\n"
525 " @result{} \"1000\"")
526 #define FUNC_NAME s_scm_logand
532 return SCM_MAKINUM (-1);
535 SCM_VALIDATE_ULONG_COPY (1,n1
,i1
);
536 SCM_VALIDATE_ULONG_COPY (2,n2
,i2
);
537 return SCM_LOGOP_RETURN (i1
& i2
);
541 SCM_DEFINE1 (scm_logior
, "logior", scm_tc7_asubr
,
543 "Returns the integer which is the bit-wise OR of the two integer\n"
547 "(number->string (logior #b1100 #b1010) 2)\n"
548 " @result{} \"1110\"\n"
550 #define FUNC_NAME s_scm_logior
559 SCM_VALIDATE_ULONG_COPY (1,n1
,i1
);
560 SCM_VALIDATE_ULONG_COPY (2,n2
,i2
);
561 return SCM_LOGOP_RETURN (i1
| i2
);
565 SCM_DEFINE1 (scm_logxor
, "logxor", scm_tc7_asubr
,
567 "Returns the integer which is the bit-wise XOR of the two integer\n"
571 "(number->string (logxor #b1100 #b1010) 2)\n"
572 " @result{} \"110\"\n"
574 #define FUNC_NAME s_scm_logxor
583 SCM_VALIDATE_ULONG_COPY (1,n1
,i1
);
584 SCM_VALIDATE_ULONG_COPY (2,n2
,i2
);
585 return SCM_LOGOP_RETURN (i1
^ i2
);
589 SCM_DEFINE (scm_logtest
, "logtest", 2, 0, 0,
592 "(logtest j k) @equiv{} (not (zero? (logand j k)))\n\n"
593 "(logtest #b0100 #b1011) @result{} #f\n"
594 "(logtest #b0100 #b0111) @result{} #t\n"
596 #define FUNC_NAME s_scm_logtest
599 SCM_VALIDATE_ULONG_COPY (1,n1
,i1
);
600 SCM_VALIDATE_ULONG_COPY (2,n2
,i2
);
601 return SCM_BOOL(i1
& i2
);
606 SCM_DEFINE (scm_logbit_p
, "logbit?", 2, 0, 0,
609 "(logbit? index j) @equiv{} (logtest (integer-expt 2 index) j)\n\n"
610 "(logbit? 0 #b1101) @result{} #t\n"
611 "(logbit? 1 #b1101) @result{} #f\n"
612 "(logbit? 2 #b1101) @result{} #t\n"
613 "(logbit? 3 #b1101) @result{} #t\n"
614 "(logbit? 4 #b1101) @result{} #f\n"
616 #define FUNC_NAME s_scm_logbit_p
619 SCM_VALIDATE_INUM_MIN_COPY (1,index
,0,i1
);
620 SCM_VALIDATE_ULONG_COPY (2,j
,i2
);
621 return SCM_BOOL((1 << i1
) & i2
);
625 SCM_DEFINE (scm_lognot
, "lognot", 1, 0, 0,
627 "Returns the integer which is the 2s-complement of the integer argument.\n\n"
630 "(number->string (lognot #b10000000) 2)\n"
631 " @result{} \"-10000001\"\n"
632 "(number->string (lognot #b0) 2)\n"
633 " @result{} \"-1\"\n"
636 #define FUNC_NAME s_scm_lognot
638 SCM_VALIDATE_INUM (1,n
);
639 return scm_difference (SCM_MAKINUM (-1L), n
);
643 SCM_DEFINE (scm_integer_expt
, "integer-expt", 2, 0, 0,
645 "Returns @var{n} raised to the non-negative integer exponent @var{k}.\n\n"
648 "(integer-expt 2 5)\n"
650 "(integer-expt -3 3)\n"
653 #define FUNC_NAME s_scm_integer_expt
655 SCM acc
= SCM_MAKINUM (1L);
658 if (SCM_INUM0
== n
|| acc
== n
)
660 else if (SCM_MAKINUM (-1L) == n
)
661 return SCM_BOOL_F
== scm_even_p (k
) ? n
: acc
;
663 SCM_VALIDATE_ULONG_COPY (2,k
,i2
);
667 n
= scm_divide (n
, SCM_UNDEFINED
);
674 return scm_product (acc
, n
);
676 acc
= scm_product (acc
, n
);
677 n
= scm_product (n
, n
);
683 SCM_DEFINE (scm_ash
, "ash", 2, 0, 0,
685 "Returns an integer equivalent to\n"
686 "@code{(inexact->exact (floor (* @var{int} (expt 2 @var{count}))))}.@refill\n\n"
689 "(number->string (ash #b1 3) 2)\n"
691 (number->string (ash #b1010 -1) 2)
694 #define FUNC_NAME s_scm_ash
696 /* GJB:FIXME:: what is going on here? */
697 SCM res
= SCM_INUM (n
);
698 SCM_VALIDATE_INUM (2,cnt
);
702 res
= scm_integer_expt (SCM_MAKINUM (2), SCM_MAKINUM (-SCM_INUM (cnt
)));
703 if (SCM_NFALSEP (scm_negative_p (n
)))
704 return scm_sum (SCM_MAKINUM (-1L),
705 scm_quotient (scm_sum (SCM_MAKINUM (1L), n
), res
));
707 return scm_quotient (n
, res
);
710 return scm_product (n
, scm_integer_expt (SCM_MAKINUM (2), cnt
));
712 SCM_VALIDATE_INUM (1,n
)
713 cnt
= SCM_INUM (cnt
);
715 return SCM_MAKINUM (SCM_SRS (res
, -cnt
));
716 res
= SCM_MAKINUM (res
<< cnt
);
717 if (SCM_INUM (res
) >> cnt
!= SCM_INUM (n
))
718 scm_num_overflow (FUNC_NAME
);
724 /* GJB:FIXME: do not use SCMs as integers! */
725 SCM_DEFINE (scm_bit_extract
, "bit-extract", 3, 0, 0,
726 (SCM n
, SCM start
, SCM end
),
727 "Returns the integer composed of the @var{start} (inclusive) through\n"
728 "@var{end} (exclusive) bits of @var{n}. The @var{start}th bit becomes\n"
729 "the 0-th bit in the result.@refill\n\n"
732 "(number->string (bit-extract #b1101101010 0 4) 2)\n"
733 " @result{} \"1010\"\n"
734 "(number->string (bit-extract #b1101101010 4 9) 2)\n"
735 " @result{} \"10110\"\n"
737 #define FUNC_NAME s_scm_bit_extract
740 SCM_VALIDATE_INUM (1,n
);
741 SCM_VALIDATE_INUM_MIN_COPY (2,start
,0,istart
);
742 SCM_VALIDATE_INUM_MIN_COPY (3, end
, 0, iend
);
743 SCM_ASSERT_RANGE (3, end
, (iend
>= istart
));
747 scm_logand (scm_difference (scm_integer_expt (SCM_MAKINUM (2),
748 SCM_MAKINUM (iend
- istart
)),
750 scm_ash (n
, SCM_MAKINUM (-istart
)));
752 SCM_VALIDATE_INUM (1,n
);
754 return SCM_MAKINUM ((SCM_INUM (n
) >> istart
) & ((1L << (iend
- istart
)) - 1));
758 static const char scm_logtab
[] = {
759 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
762 SCM_DEFINE (scm_logcount
, "logcount", 1, 0, 0,
764 "Returns the number of bits in integer @var{n}. If integer is positive,\n"
765 "the 1-bits in its binary representation are counted. If negative, the\n"
766 "0-bits in its two's-complement binary representation are counted. If 0,\n"
770 "(logcount #b10101010)\n"
777 #define FUNC_NAME s_scm_logcount
779 register unsigned long c
= 0;
786 SCM_VALIDATE_BIGINT (1,n
);
788 return scm_logcount (scm_difference (SCM_MAKINUM (-1L), n
));
789 ds
= SCM_BDIGITS (n
);
790 for (i
= SCM_NUMDIGS (n
); i
--;)
791 for (d
= ds
[i
]; d
; d
>>= 4)
792 c
+= scm_logtab
[15 & d
];
793 return SCM_MAKINUM (c
);
796 SCM_VALIDATE_INUM (1,n
);
798 if ((nn
= SCM_INUM (n
)) < 0)
801 c
+= scm_logtab
[15 & nn
];
802 return SCM_MAKINUM (c
);
807 static const char scm_ilentab
[] = {
808 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
811 SCM_DEFINE (scm_integer_length
, "integer-length", 1, 0, 0,
813 "Returns the number of bits neccessary to represent @var{n}.\n\n"
816 "(integer-length #b10101010)\n"
818 "(integer-length 0)\n"
820 "(integer-length #b1111)\n"
823 #define FUNC_NAME s_scm_integer_length
825 register unsigned long c
= 0;
832 SCM_VALIDATE_BIGINT (1,n
);
834 return scm_integer_length (scm_difference (SCM_MAKINUM (-1L), n
));
835 ds
= SCM_BDIGITS (n
);
836 d
= ds
[c
= SCM_NUMDIGS (n
) - 1];
837 for (c
*= SCM_BITSPERDIG
; d
; d
>>= 4)
840 l
= scm_ilentab
[15 & d
];
842 return SCM_MAKINUM (c
- 4 + l
);
845 SCM_VALIDATE_INUM (1,n
);
847 if ((nn
= SCM_INUM (n
)) < 0)
852 l
= scm_ilentab
[15 & nn
];
854 return SCM_MAKINUM (c
- 4 + l
);
860 static const char s_bignum
[] = "bignum";
863 scm_mkbig (scm_sizet nlen
, int sign
)
866 /* Cast to SCM to avoid signed/unsigned comparison warnings. */
867 if (((v
<< 16) >> 16) != (SCM
) nlen
)
868 scm_wta (SCM_MAKINUM (nlen
), (char *) SCM_NALLOC
, s_bignum
);
871 SCM_SETCHARS (v
, scm_must_malloc ((long) (nlen
* sizeof (SCM_BIGDIG
)),
873 SCM_SETNUMDIGS (v
, nlen
, sign
? scm_tc16_bigneg
: scm_tc16_bigpos
);
880 scm_big2inum (SCM b
, scm_sizet l
)
882 unsigned long num
= 0;
883 SCM_BIGDIG
*tmp
= SCM_BDIGITS (b
);
885 num
= SCM_BIGUP (num
) + tmp
[l
];
886 if (SCM_TYP16 (b
) == scm_tc16_bigpos
)
888 if (SCM_POSFIXABLE (num
))
889 return SCM_MAKINUM (num
);
891 else if (SCM_UNEGFIXABLE (num
))
892 return SCM_MAKINUM (-num
);
897 static const char s_adjbig
[] = "scm_adjbig";
900 scm_adjbig (SCM b
, scm_sizet nlen
)
902 scm_sizet nsiz
= nlen
;
903 if (((nsiz
<< 16) >> 16) != nlen
)
904 scm_wta (scm_ulong2num (nsiz
), (char *) SCM_NALLOC
, s_adjbig
);
910 scm_must_realloc ((char *) SCM_CHARS (b
),
911 (long) (SCM_NUMDIGS (b
) * sizeof (SCM_BIGDIG
)),
912 (long) (nsiz
* sizeof (SCM_BIGDIG
)), s_adjbig
));
914 SCM_SETCHARS (b
, digits
);
915 SCM_SETNUMDIGS (b
, nsiz
, SCM_TYP16 (b
));
927 scm_sizet nlen
= SCM_NUMDIGS (b
);
929 int nlen
= SCM_NUMDIGS (b
); /* unsigned nlen breaks on Cray when nlen => 0 */
931 SCM_BIGDIG
*zds
= SCM_BDIGITS (b
);
932 while (nlen
-- && !zds
[nlen
]);
934 if (nlen
* SCM_BITSPERDIG
/ SCM_CHAR_BIT
<= sizeof (SCM
))
935 if (SCM_INUMP (b
= scm_big2inum (b
, (scm_sizet
) nlen
)))
937 if (SCM_NUMDIGS (b
) == nlen
)
939 return scm_adjbig (b
, (scm_sizet
) nlen
);
945 scm_copybig (SCM b
, int sign
)
947 scm_sizet i
= SCM_NUMDIGS (b
);
948 SCM ans
= scm_mkbig (i
, sign
);
949 SCM_BIGDIG
*src
= SCM_BDIGITS (b
), *dst
= SCM_BDIGITS (ans
);
958 scm_long2big (long n
)
962 SCM ans
= scm_mkbig (SCM_DIGSPERLONG
, n
< 0);
963 digits
= SCM_BDIGITS (ans
);
966 while (i
< SCM_DIGSPERLONG
)
968 digits
[i
++] = SCM_BIGLO (n
);
969 n
= SCM_BIGDN ((unsigned long) n
);
974 #ifdef HAVE_LONG_LONGS
977 scm_long_long2big (long_long n
)
987 if ((long long) tn
== n
)
988 return scm_long2big (tn
);
994 for (tn
= n
, n_digits
= 0;
996 ++n_digits
, tn
= SCM_BIGDN ((ulong_long
) tn
))
1001 ans
= scm_mkbig (n_digits
, n
< 0);
1002 digits
= SCM_BDIGITS (ans
);
1005 while (i
< n_digits
)
1007 digits
[i
++] = SCM_BIGLO (n
);
1008 n
= SCM_BIGDN ((ulong_long
) n
);
1016 scm_2ulong2big (unsigned long *np
)
1023 ans
= scm_mkbig (2 * SCM_DIGSPERLONG
, 0);
1024 digits
= SCM_BDIGITS (ans
);
1027 for (i
= 0; i
< SCM_DIGSPERLONG
; ++i
)
1029 digits
[i
] = SCM_BIGLO (n
);
1030 n
= SCM_BIGDN ((unsigned long) n
);
1033 for (i
= 0; i
< SCM_DIGSPERLONG
; ++i
)
1035 digits
[i
+ SCM_DIGSPERLONG
] = SCM_BIGLO (n
);
1036 n
= SCM_BIGDN ((unsigned long) n
);
1044 scm_ulong2big (unsigned long n
)
1048 SCM ans
= scm_mkbig (SCM_DIGSPERLONG
, 0);
1049 digits
= SCM_BDIGITS (ans
);
1050 while (i
< SCM_DIGSPERLONG
)
1052 digits
[i
++] = SCM_BIGLO (n
);
1061 scm_bigcomp (SCM x
, SCM y
)
1063 int xsign
= SCM_BIGSIGN (x
);
1064 int ysign
= SCM_BIGSIGN (y
);
1065 scm_sizet xlen
, ylen
;
1067 /* Look at the signs, first. */
1073 /* They're the same sign, so see which one has more digits. Note
1074 that, if they are negative, the longer number is the lesser. */
1075 ylen
= SCM_NUMDIGS (y
);
1076 xlen
= SCM_NUMDIGS (x
);
1078 return (xsign
) ? -1 : 1;
1080 return (xsign
) ? 1 : -1;
1082 /* They have the same number of digits, so find the most significant
1083 digit where they differ. */
1087 if (SCM_BDIGITS (y
)[xlen
] != SCM_BDIGITS (x
)[xlen
])
1088 /* Make the discrimination based on the digit that differs. */
1089 return ((SCM_BDIGITS (y
)[xlen
] > SCM_BDIGITS (x
)[xlen
])
1091 : (xsign
? 1 : -1));
1094 /* The numbers are identical. */
1098 #ifndef SCM_DIGSTOOBIG
1102 scm_pseudolong (long x
)
1107 SCM_BIGDIG bd
[SCM_DIGSPERLONG
];
1113 while (i
< SCM_DIGSPERLONG
)
1115 p
.bd
[i
++] = SCM_BIGLO (x
);
1118 /* p.bd[0] = SCM_BIGLO(x); p.bd[1] = SCM_BIGDN(x); */
1126 scm_longdigs (long x
, SCM_BIGDIG digs
[])
1131 while (i
< SCM_DIGSPERLONG
)
1133 digs
[i
++] = SCM_BIGLO (x
);
1142 scm_addbig (SCM_BIGDIG
*x
, scm_sizet nx
, int xsgn
, SCM bigy
, int sgny
)
1144 /* Assumes nx <= SCM_NUMDIGS(bigy) */
1145 /* Assumes xsgn and sgny scm_equal either 0 or 0x0100 */
1147 scm_sizet i
= 0, ny
= SCM_NUMDIGS (bigy
);
1148 SCM z
= scm_copybig (bigy
, SCM_BIGSIGN (bigy
) ^ sgny
);
1149 SCM_BIGDIG
*zds
= SCM_BDIGITS (z
);
1150 if (xsgn
^ SCM_BIGSIGN (z
))
1154 num
+= (long) zds
[i
] - x
[i
];
1157 zds
[i
] = num
+ SCM_BIGRAD
;
1162 zds
[i
] = SCM_BIGLO (num
);
1167 if (num
&& nx
== ny
)
1171 SCM_SETCAR (z
, SCM_CAR (z
) ^ 0x0100);
1174 num
+= (SCM_BIGRAD
- 1) - zds
[i
];
1175 zds
[i
++] = SCM_BIGLO (num
);
1176 num
= SCM_BIGDN (num
);
1186 zds
[i
++] = num
+ SCM_BIGRAD
;
1191 zds
[i
++] = SCM_BIGLO (num
);
1200 num
+= (long) zds
[i
] + x
[i
];
1201 zds
[i
++] = SCM_BIGLO (num
);
1202 num
= SCM_BIGDN (num
);
1210 zds
[i
++] = SCM_BIGLO (num
);
1211 num
= SCM_BIGDN (num
);
1217 z
= scm_adjbig (z
, ny
+ 1);
1218 SCM_BDIGITS (z
)[ny
] = num
;
1222 return scm_normbig (z
);
1227 scm_mulbig (SCM_BIGDIG
*x
, scm_sizet nx
, SCM_BIGDIG
*y
, scm_sizet ny
, int sgn
)
1229 scm_sizet i
= 0, j
= nx
+ ny
;
1230 unsigned long n
= 0;
1231 SCM z
= scm_mkbig (j
, sgn
);
1232 SCM_BIGDIG
*zds
= SCM_BDIGITS (z
);
1242 n
+= zds
[i
+ j
] + ((unsigned long) x
[i
] * y
[j
]);
1243 zds
[i
+ j
++] = SCM_BIGLO (n
);
1255 return scm_normbig (z
);
1259 /* Sun's compiler complains about the fact that this function has an
1260 ANSI prototype in numbers.h, but a K&R declaration here, and the
1261 two specify different promotions for the third argument. I'm going
1262 to turn this into an ANSI declaration, and see if anyone complains
1263 about it not being K&R. */
1266 scm_divbigdig (SCM_BIGDIG
* ds
,
1270 register unsigned long t2
= 0;
1273 t2
= SCM_BIGUP (t2
) + ds
[h
];
1283 scm_divbigint (SCM x
, long z
, int sgn
, int mode
)
1289 register unsigned long t2
= 0;
1290 register SCM_BIGDIG
*ds
= SCM_BDIGITS (x
);
1291 scm_sizet nd
= SCM_NUMDIGS (x
);
1293 t2
= (SCM_BIGUP (t2
) + ds
[nd
]) % z
;
1296 return SCM_MAKINUM (sgn
? -t2
: t2
);
1299 #ifndef SCM_DIGSTOOBIG
1300 unsigned long t2
= scm_pseudolong (z
);
1301 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
1302 (SCM_BIGDIG
*) & t2
, SCM_DIGSPERLONG
,
1305 SCM_BIGDIG t2
[SCM_DIGSPERLONG
];
1306 scm_longdigs (z
, t2
);
1307 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
1308 t2
, SCM_DIGSPERLONG
,
1316 scm_divbigbig (SCM_BIGDIG
*x
, scm_sizet nx
, SCM_BIGDIG
*y
, scm_sizet ny
, int sgn
, int modes
)
1318 /* modes description
1322 3 quotient but returns 0 if division is not exact. */
1323 scm_sizet i
= 0, j
= 0;
1325 unsigned long t2
= 0;
1327 SCM_BIGDIG d
= 0, qhat
, *zds
, *yds
;
1328 /* algorithm requires nx >= ny */
1332 case 0: /* remainder -- just return x */
1333 z
= scm_mkbig (nx
, sgn
);
1334 zds
= SCM_BDIGITS (z
);
1341 case 1: /* scm_modulo -- return y-x */
1342 z
= scm_mkbig (ny
, sgn
);
1343 zds
= SCM_BDIGITS (z
);
1346 num
+= (long) y
[i
] - x
[i
];
1349 zds
[i
] = num
+ SCM_BIGRAD
;
1364 zds
[i
++] = num
+ SCM_BIGRAD
;
1375 return SCM_INUM0
; /* quotient is zero */
1377 return 0; /* the division is not exact */
1380 z
= scm_mkbig (nx
== ny
? nx
+ 2 : nx
+ 1, sgn
);
1381 zds
= SCM_BDIGITS (z
);
1385 ny
--; /* in case y came in as a psuedolong */
1386 if (y
[ny
- 1] < (SCM_BIGRAD
>> 1))
1387 { /* normalize operands */
1388 d
= SCM_BIGRAD
/ (y
[ny
- 1] + 1);
1389 newy
= scm_mkbig (ny
, 0);
1390 yds
= SCM_BDIGITS (newy
);
1393 t2
+= (unsigned long) y
[j
] * d
;
1394 yds
[j
++] = SCM_BIGLO (t2
);
1395 t2
= SCM_BIGDN (t2
);
1402 t2
+= (unsigned long) x
[j
] * d
;
1403 zds
[j
++] = SCM_BIGLO (t2
);
1404 t2
= SCM_BIGDN (t2
);
1414 j
= nx
== ny
? nx
+ 1 : nx
; /* dividend needs more digits than divisor */
1416 { /* loop over digits of quotient */
1417 if (zds
[j
] == y
[ny
- 1])
1418 qhat
= SCM_BIGRAD
- 1;
1420 qhat
= (SCM_BIGUP (zds
[j
]) + zds
[j
- 1]) / y
[ny
- 1];
1427 { /* multiply and subtract */
1428 t2
+= (unsigned long) y
[i
] * qhat
;
1429 num
+= zds
[j
- ny
+ i
] - SCM_BIGLO (t2
);
1432 zds
[j
- ny
+ i
] = num
+ SCM_BIGRAD
;
1437 zds
[j
- ny
+ i
] = num
;
1440 t2
= SCM_BIGDN (t2
);
1443 num
+= zds
[j
- ny
+ i
] - t2
; /* borrow from high digit; don't update */
1445 { /* "add back" required */
1451 num
+= (long) zds
[j
- ny
+ i
] + y
[i
];
1452 zds
[j
- ny
+ i
] = SCM_BIGLO (num
);
1453 num
= SCM_BIGDN (num
);
1464 case 3: /* check that remainder==0 */
1465 for (j
= ny
; j
&& !zds
[j
- 1]; --j
);
1468 case 2: /* move quotient down in z */
1469 j
= (nx
== ny
? nx
+ 2 : nx
+ 1) - ny
;
1470 for (i
= 0; i
< j
; i
++)
1471 zds
[i
] = zds
[i
+ ny
];
1474 case 1: /* subtract for scm_modulo */
1480 num
+= y
[i
] - zds
[i
];
1484 zds
[i
] = num
+ SCM_BIGRAD
;
1496 case 0: /* just normalize remainder */
1498 scm_divbigdig (zds
, ny
, d
);
1501 for (j
= ny
; j
&& !zds
[j
- 1]; --j
);
1502 if (j
* SCM_BITSPERDIG
<= sizeof (SCM
) * SCM_CHAR_BIT
)
1503 if (SCM_INUMP (z
= scm_big2inum (z
, j
)))
1505 return scm_adjbig (z
, j
);
1513 /*** NUMBERS -> STRINGS ***/
1516 static const double fx
[] =
1517 { 0.0, 5e-1, 5e-2, 5e-3, 5e-4, 5e-5,
1518 5e-6, 5e-7, 5e-8, 5e-9, 5e-10,
1519 5e-11, 5e-12, 5e-13, 5e-14, 5e-15,
1520 5e-16, 5e-17, 5e-18, 5e-19, 5e-20};
1526 idbl2str (double f
, char *a
)
1528 int efmt
, dpt
, d
, i
, wp
= scm_dblprec
;
1533 goto zero
; /*{a[0]='0'; a[1]='.'; a[2]='0'; return 3;} */
1552 #ifdef DBL_MIN_10_EXP /* Prevent unnormalized values, as from
1553 make-uniform-vector, from causing infinite loops. */
1557 if (exp
-- < DBL_MIN_10_EXP
)
1563 if (exp
++ > DBL_MAX_10_EXP
)
1578 if (f
+ fx
[wp
] >= 10.0)
1585 dpt
= (exp
+ 9999) % 3;
1589 efmt
= (exp
< -3) || (exp
> wp
+ 2);
1614 if (f
+ fx
[wp
] >= 1.0)
1628 if ((dpt
> 4) && (exp
> 6))
1630 d
= (a
[0] == '-' ? 2 : 1);
1631 for (i
= ch
++; i
> d
; i
--)
1644 if (a
[ch
- 1] == '.')
1645 a
[ch
++] = '0'; /* trailing zero */
1654 for (i
= 10; i
<= exp
; i
*= 10);
1655 for (i
/= 10; i
; i
/= 10)
1657 a
[ch
++] = exp
/ i
+ '0';
1666 iflo2str (SCM flt
, char *str
)
1670 if (SCM_SINGP (flt
))
1671 i
= idbl2str (SCM_FLO (flt
), str
);
1674 i
= idbl2str (SCM_REAL (flt
), str
);
1675 if (SCM_CPLXP (flt
))
1677 if (0 <= SCM_IMAG (flt
)) /* jeh */
1678 str
[i
++] = '+'; /* jeh */
1679 i
+= idbl2str (SCM_IMAG (flt
), &str
[i
]);
1684 #endif /* SCM_FLOATS */
1686 /* convert a long to a string (unterminated). returns the number of
1687 characters in the result.
1689 p is destination: worst case (base 2) is SCM_INTBUFLEN */
1691 scm_iint2str (long num
, int rad
, char *p
)
1695 unsigned long n
= (num
< 0) ? -num
: num
;
1697 for (n
/= rad
; n
> 0; n
/= rad
)
1714 p
[i
] = d
+ ((d
< 10) ? '0' : 'a' - 10);
1723 big2str (SCM b
, unsigned int radix
)
1725 SCM t
= scm_copybig (b
, 0); /* sign of temp doesn't matter */
1726 register SCM_BIGDIG
*ds
= SCM_BDIGITS (t
);
1727 scm_sizet i
= SCM_NUMDIGS (t
);
1728 scm_sizet j
= radix
== 16 ? (SCM_BITSPERDIG
* i
) / 4 + 2
1729 : radix
>= 10 ? (SCM_BITSPERDIG
* i
* 241L) / 800 + 2
1730 : (SCM_BITSPERDIG
* i
) + 2;
1732 scm_sizet radct
= 0;
1733 scm_sizet ch
; /* jeh */
1734 SCM_BIGDIG radpow
= 1, radmod
= 0;
1735 SCM ss
= scm_makstr ((long) j
, 0);
1736 char *s
= SCM_CHARS (ss
), c
;
1737 while ((long) radpow
* radix
< SCM_BIGRAD
)
1742 s
[0] = scm_tc16_bigneg
== SCM_TYP16 (b
) ? '-' : '+';
1743 while ((i
|| radmod
) && j
)
1747 radmod
= (SCM_BIGDIG
) scm_divbigdig (ds
, i
, radpow
);
1755 s
[--j
] = c
< 10 ? c
+ '0' : c
+ 'a' - 10;
1757 ch
= s
[0] == '-' ? 1 : 0; /* jeh */
1760 for (i
= j
; j
< SCM_LENGTH (ss
); j
++)
1761 s
[ch
+ j
- i
] = s
[j
]; /* jeh */
1762 scm_vector_set_length_x (ss
, /* jeh */
1763 (SCM
) SCM_MAKINUM (ch
+ SCM_LENGTH (ss
) - i
));
1766 return scm_return_first (ss
, t
);
1771 SCM_DEFINE (scm_number_to_string
, "number->string", 1, 1, 0,
1774 #define FUNC_NAME s_scm_number_to_string
1777 SCM_VALIDATE_INUM_MIN_DEF_COPY (2,radix
,2,10,base
);
1781 char num_buf
[SCM_FLOBUFLEN
];
1783 SCM_ASRTGO (SCM_NIMP (x
), badx
);
1785 return big2str (x
, (unsigned int) base
);
1786 #ifndef SCM_RECKLESS
1794 SCM_ASSERT (SCM_INEXP (x
),
1795 x
, SCM_ARG1
, s_number_to_string
);
1797 return scm_makfromstr (num_buf
, iflo2str (x
, num_buf
), 0);
1803 SCM_ASSERT (SCM_BIGP (x
),
1804 x
, SCM_ARG1
, s_number_to_string
);
1805 return big2str (x
, (unsigned int) base
);
1808 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_number_to_string
);
1812 char num_buf
[SCM_INTBUFLEN
];
1813 return scm_makfromstr (num_buf
,
1814 scm_iint2str (SCM_INUM (x
),
1823 /* These print routines are stubbed here so that scm_repl.c doesn't need
1824 SCM_FLOATS or SCM_BIGDIGs conditionals */
1827 scm_floprint (SCM sexp
, SCM port
, scm_print_state
*pstate
)
1830 char num_buf
[SCM_FLOBUFLEN
];
1831 scm_lfwrite (num_buf
, iflo2str (sexp
, num_buf
), port
);
1833 scm_ipruk ("float", sexp
, port
);
1841 scm_bigprint (SCM exp
, SCM port
, scm_print_state
*pstate
)
1844 exp
= big2str (exp
, (unsigned int) 10);
1845 scm_lfwrite (SCM_CHARS (exp
), (scm_sizet
) SCM_LENGTH (exp
), port
);
1847 scm_ipruk ("bignum", exp
, port
);
1851 /*** END nums->strs ***/
1853 /*** STRINGS -> NUMBERS ***/
1856 scm_small_istr2int (char *str
, long len
, long radix
)
1858 register long n
= 0, ln
;
1863 return SCM_BOOL_F
; /* zero scm_length */
1865 { /* leading sign */
1870 return SCM_BOOL_F
; /* bad if lone `+' or `-' */
1875 switch (c
= str
[i
++])
1897 return SCM_BOOL_F
; /* bad digit for radix */
1900 /* Negation is a workaround for HP700 cc bug */
1901 if (n
> ln
|| (-n
> -SCM_MOST_NEGATIVE_FIXNUM
))
1905 return SCM_BOOL_F
; /* not a digit */
1910 if ((n
= -n
) > SCM_MOST_POSITIVE_FIXNUM
)
1912 return SCM_MAKINUM (n
);
1913 ovfl
: /* overflow scheme integer */
1920 scm_istr2int (char *str
, long len
, long radix
)
1923 register scm_sizet k
, blen
= 1;
1927 register SCM_BIGDIG
*ds
;
1928 register unsigned long t2
;
1931 return SCM_BOOL_F
; /* zero scm_length */
1933 /* Short numbers we parse directly into an int, to avoid the overhead
1934 of creating a bignum. */
1936 return scm_small_istr2int (str
, len
, radix
);
1939 j
= 1 + (4 * len
* sizeof (char)) / (SCM_BITSPERDIG
);
1940 else if (10 <= radix
)
1941 j
= 1 + (84 * len
* sizeof (char)) / (SCM_BITSPERDIG
* 25);
1943 j
= 1 + (len
* sizeof (char)) / (SCM_BITSPERDIG
);
1945 { /* leading sign */
1948 if (++i
== (unsigned) len
)
1949 return SCM_BOOL_F
; /* bad if lone `+' or `-' */
1951 res
= scm_mkbig (j
, '-' == str
[0]);
1952 ds
= SCM_BDIGITS (res
);
1957 switch (c
= str
[i
++])
1979 return SCM_BOOL_F
; /* bad digit for radix */
1985 /* printf ("k = %d, blen = %d, t2 = %ld, ds[k] = %d\n", k, blen, t2, ds[k]); */
1986 t2
+= ds
[k
] * radix
;
1987 ds
[k
++] = SCM_BIGLO (t2
);
1988 t2
= SCM_BIGDN (t2
);
1991 scm_num_overflow ("bignum");
1999 return SCM_BOOL_F
; /* not a digit */
2002 while (i
< (unsigned) len
);
2003 if (blen
* SCM_BITSPERDIG
/ SCM_CHAR_BIT
<= sizeof (SCM
))
2004 if (SCM_INUMP (res
= scm_big2inum (res
, blen
)))
2008 return scm_adjbig (res
, blen
);
2014 scm_istr2flo (char *str
, long len
, long radix
)
2016 register int c
, i
= 0;
2018 double res
= 0.0, tmp
= 0.0;
2024 return SCM_BOOL_F
; /* zero scm_length */
2027 { /* leading sign */
2040 return SCM_BOOL_F
; /* bad if lone `+' or `-' */
2042 if (str
[i
] == 'i' || str
[i
] == 'I')
2043 { /* handle `+i' and `-i' */
2044 if (lead_sgn
== 0.0)
2045 return SCM_BOOL_F
; /* must have leading sign */
2047 return SCM_BOOL_F
; /* `i' not last character */
2048 return scm_makdbl (0.0, lead_sgn
);
2051 { /* check initial digits */
2061 goto out1
; /* must be exponent */
2078 return SCM_BOOL_F
; /* bad digit for radix */
2079 res
= res
* radix
+ c
;
2080 flg
= 1; /* res is valid */
2089 /* if true, then we did see a digit above, and res is valid */
2093 /* By here, must have seen a digit,
2094 or must have next char be a `.' with radix==10 */
2096 if (!(str
[i
] == '.' && radix
== 10))
2099 while (str
[i
] == '#')
2100 { /* optional sharps */
2133 tmp
= tmp
* radix
+ c
;
2141 return SCM_BOOL_F
; /* `slash zero' not allowed */
2143 while (str
[i
] == '#')
2144 { /* optional sharps */
2154 { /* decimal point notation */
2156 return SCM_BOOL_F
; /* must be radix 10 */
2163 res
= res
* 10.0 + c
- '0';
2172 return SCM_BOOL_F
; /* no digits before or after decimal point */
2175 while (str
[i
] == '#')
2176 { /* ignore remaining sharps */
2195 int expsgn
= 1, expon
= 0;
2197 return SCM_BOOL_F
; /* only in radix 10 */
2199 return SCM_BOOL_F
; /* bad exponent */
2206 return SCM_BOOL_F
; /* bad exponent */
2208 if (str
[i
] < '0' || str
[i
] > '9')
2209 return SCM_BOOL_F
; /* bad exponent */
2215 expon
= expon
* 10 + c
- '0';
2217 return SCM_BOOL_F
; /* exponent too large */
2225 point
+= expsgn
* expon
;
2243 /* at this point, we have a legitimate floating point result */
2244 if (lead_sgn
== -1.0)
2247 return scm_makdbl (res
, 0.0);
2249 if (str
[i
] == 'i' || str
[i
] == 'I')
2250 { /* pure imaginary number */
2251 if (lead_sgn
== 0.0)
2252 return SCM_BOOL_F
; /* must have leading sign */
2254 return SCM_BOOL_F
; /* `i' not last character */
2255 return scm_makdbl (0.0, res
);
2267 { /* polar input for complex number */
2268 /* get a `real' for scm_angle */
2269 second
= scm_istr2flo (&str
[i
], (long) (len
- i
), radix
);
2270 if (!SCM_INEXP (second
))
2271 return SCM_BOOL_F
; /* not `real' */
2272 if (SCM_CPLXP (second
))
2273 return SCM_BOOL_F
; /* not `real' */
2274 tmp
= SCM_REALPART (second
);
2275 return scm_makdbl (res
* cos (tmp
), res
* sin (tmp
));
2281 /* at this point, last char must be `i' */
2282 if (str
[len
- 1] != 'i' && str
[len
- 1] != 'I')
2284 /* handles `x+i' and `x-i' */
2286 return scm_makdbl (res
, lead_sgn
);
2287 /* get a `ureal' for complex part */
2288 second
= scm_istr2flo (&str
[i
], (long) ((len
- i
) - 1), radix
);
2289 if (!SCM_INEXP (second
))
2290 return SCM_BOOL_F
; /* not `ureal' */
2291 if (SCM_CPLXP (second
))
2292 return SCM_BOOL_F
; /* not `ureal' */
2293 tmp
= SCM_REALPART (second
);
2295 return SCM_BOOL_F
; /* not `ureal' */
2296 return scm_makdbl (res
, (lead_sgn
* tmp
));
2298 #endif /* SCM_FLOATS */
2303 scm_istring2number (char *str
, long len
, long radix
)
2307 char ex_p
= 0, rx_p
= 0; /* Only allow 1 exactness and 1 radix prefix */
2310 if (*str
== '+' || *str
== '-') /* Catches lone `+' and `-' for speed */
2313 while ((len
- i
) >= 2 && str
[i
] == '#' && ++i
)
2359 return scm_istr2int (&str
[i
], len
- i
, radix
);
2361 res
= scm_istr2int (&str
[i
], len
- i
, radix
);
2362 if (SCM_NFALSEP (res
))
2366 return scm_istr2flo (&str
[i
], len
- i
, radix
);
2373 SCM_DEFINE (scm_string_to_number
, "string->number", 1, 1, 0,
2374 (SCM str
, SCM radix
),
2376 #define FUNC_NAME s_scm_string_to_number
2380 SCM_VALIDATE_ROSTRING (1,str
);
2381 SCM_VALIDATE_INUM_MIN_DEF_COPY (2,radix
,2,10,base
);
2382 answer
= scm_istring2number (SCM_ROCHARS (str
),
2385 return scm_return_first (answer
, str
);
2388 /*** END strs->nums ***/
2393 scm_makdbl (double x
, double y
)
2396 if ((y
== 0.0) && (x
== 0.0))
2403 #ifndef SCM_SINGLESONLY
2404 if ((-FLTMAX
< x
) && (x
< FLTMAX
) && (fx
== x
))
2407 SCM_NEWSMOB(z
,scm_tc_flo
,NULL
);
2412 #endif /* def SCM_SINGLES */
2413 SCM_NEWSMOB(z
,scm_tc_dblr
,scm_must_malloc (1L * sizeof (double), "real"));
2417 SCM_NEWSMOB(z
,scm_tc_dblc
,scm_must_malloc (2L * sizeof (double), "comkplex"));
2429 scm_bigequal (SCM x
, SCM y
)
2432 if (0 == scm_bigcomp (x
, y
))
2441 scm_floequal (SCM x
, SCM y
)
2444 if (SCM_REALPART (x
) != SCM_REALPART (y
))
2446 if (!(SCM_CPLXP (x
) && (SCM_IMAG (x
) != SCM_IMAG (y
))))
2455 SCM_REGISTER_PROC (s_number_p
, "number?", 1, 0, 0, scm_number_p
);
2457 SCM_DEFINE (scm_number_p
, "complex?", 1, 0, 0,
2460 #define FUNC_NAME s_scm_number_p
2480 SCM_REGISTER_PROC (s_real_p
, "real?", 1, 0, 0, scm_real_p
);
2483 SCM_DEFINE (scm_real_p
, "rational?", 1, 0, 0,
2486 #define FUNC_NAME s_scm_real_p
2504 SCM_DEFINE (scm_integer_p
, "integer?", 1, 0, 0,
2507 #define FUNC_NAME s_scm_integer_p
2522 r
= SCM_REALPART (x
);
2531 #endif /* SCM_FLOATS */
2533 SCM_DEFINE (scm_inexact_p
, "inexact?", 1, 0, 0,
2536 #define FUNC_NAME s_scm_inexact_p
2549 SCM_GPROC1 (s_eq_p
, "=", scm_tc7_rpsubr
, scm_num_eq_p
, g_eq_p
);
2552 scm_num_eq_p (SCM x
, SCM y
)
2562 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2568 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2570 return SCM_BOOL(0 == scm_bigcomp (x
, y
));
2571 SCM_ASRTGO (SCM_INEXP (y
), bady
);
2573 return ((SCM_REALP (y
) && (scm_big2dbl (x
) == SCM_REALPART (y
)))
2577 SCM_ASRTGO (SCM_INEXP (x
), badx
);
2579 SCM_GASSERT2 (SCM_INEXP (x
),
2580 g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2590 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2598 SCM_ASRTGO (SCM_INEXP (y
), bady
);
2600 SCM_ASRTGO (SCM_INEXP (y
), bady
);
2602 if (SCM_REALPART (x
) != SCM_REALPART (y
))
2605 return ((SCM_CPLXP (y
) && (SCM_IMAG (x
) == SCM_IMAG (y
)))
2608 return SCM_NEGATE_BOOL(SCM_CPLXP (y
));
2613 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2619 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2625 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2629 return ((SCM_REALP (y
) && (((double) SCM_INUM (x
)) == SCM_REALPART (y
)))
2637 SCM_GASSERT2 (SCM_BIGP (x
),
2638 g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2641 SCM_ASRTGO (SCM_BIGP (y
), bady
);
2642 return SCM_BOOL(0 == scm_bigcomp (x
, y
));
2649 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2654 SCM_GASSERT2 (SCM_INUMP (x
), g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2655 SCM_GASSERT2 (SCM_INUMP (y
), g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2658 return SCM_BOOL((long) x
== (long) y
);
2663 SCM_GPROC1 (s_less_p
, "<", scm_tc7_rpsubr
, scm_less_p
, g_less_p
);
2666 scm_less_p (SCM x
, SCM y
)
2675 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2680 return SCM_BOOL(SCM_BIGSIGN (x
));
2681 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2683 return SCM_BOOL(1 == scm_bigcomp (x
, y
));
2684 SCM_ASRTGO (SCM_REALP (y
), bady
);
2685 return ((scm_big2dbl (x
) < SCM_REALPART (y
))
2689 SCM_ASRTGO (SCM_REALP (x
), badx
);
2691 SCM_GASSERT2 (SCM_REALP (x
),
2692 g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2695 return ((SCM_REALPART (x
) < ((double) SCM_INUM (y
)))
2699 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2701 return SCM_BOOL(SCM_REALPART (x
) < scm_big2dbl (y
));
2702 SCM_ASRTGO (SCM_REALP (y
), bady
);
2704 SCM_ASRTGO (SCM_REALP (y
), bady
);
2706 return SCM_BOOL(SCM_REALPART (x
) < SCM_REALPART (y
));
2711 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2713 return SCM_NEGATE_BOOL(SCM_BIGSIGN (y
));
2717 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2723 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2726 return ((((double) SCM_INUM (x
)) < SCM_REALPART (y
))
2734 SCM_GASSERT2 (SCM_BIGP (x
),
2735 g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2737 return SCM_BOOL(SCM_BIGSIGN (x
));
2738 SCM_ASRTGO (SCM_BIGP (y
), bady
);
2739 return SCM_BOOL(1 == scm_bigcomp (x
, y
));
2746 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2748 return SCM_NEGATE_BOOL(SCM_BIGSIGN (y
));
2751 SCM_GASSERT2 (SCM_INUMP (x
), g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2752 SCM_GASSERT2 (SCM_INUMP (y
), g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2755 return SCM_BOOL((long) x
< (long) y
);
2759 SCM_DEFINE1 (scm_gr_p
, ">", scm_tc7_rpsubr
,
2762 #define FUNC_NAME s_scm_gr_p
2764 return scm_less_p (y
, x
);
2770 SCM_DEFINE1 (scm_leq_p
, "<=", scm_tc7_rpsubr
,
2773 #define FUNC_NAME s_scm_leq_p
2775 return SCM_BOOL_NOT (scm_less_p (y
, x
));
2781 SCM_DEFINE1 (scm_geq_p
, ">=", scm_tc7_rpsubr
,
2784 #define FUNC_NAME s_scm_geq_p
2786 return SCM_BOOL_NOT (scm_less_p (x
, y
));
2792 SCM_GPROC (s_zero_p
, "zero?", 1, 0, 0, scm_zero_p
, g_zero_p
);
2801 SCM_ASRTGO (SCM_NIMP (z
), badz
);
2807 SCM_WTA_DISPATCH_1 (g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2810 SCM_GASSERT1 (SCM_INEXP (z
),
2811 g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2813 return SCM_BOOL(z
== scm_flo0
);
2819 SCM_GASSERT1 (SCM_BIGP (z
),
2820 g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2824 SCM_GASSERT1 (SCM_INUMP (z
), g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2827 return SCM_BOOL(z
== SCM_INUM0
);
2832 SCM_GPROC (s_positive_p
, "positive?", 1, 0, 0, scm_positive_p
, g_positive_p
);
2835 scm_positive_p (SCM x
)
2841 SCM_ASRTGO (SCM_NIMP (x
), badx
);
2843 return SCM_BOOL(SCM_TYP16 (x
) == scm_tc16_bigpos
);
2847 SCM_WTA_DISPATCH_1 (g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2850 SCM_GASSERT1 (SCM_REALP (x
),
2851 g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2853 return SCM_BOOL(SCM_REALPART (x
) > 0.0);
2859 SCM_GASSERT1 (SCM_BIGP (x
),
2860 g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2861 return SCM_BOOL(SCM_TYP16 (x
) == scm_tc16_bigpos
);
2864 SCM_GASSERT1 (SCM_INUMP (x
), g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2867 return SCM_BOOL(x
> SCM_INUM0
);
2872 SCM_GPROC (s_negative_p
, "negative?", 1, 0, 0, scm_negative_p
, g_negative_p
);
2875 scm_negative_p (SCM x
)
2881 SCM_ASRTGO (SCM_NIMP (x
), badx
);
2883 return SCM_NEGATE_BOOL(SCM_TYP16 (x
) == scm_tc16_bigpos
);
2884 if (!(SCM_REALP (x
)))
2887 SCM_WTA_DISPATCH_1 (g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2890 SCM_GASSERT1 (SCM_REALP (x
),
2891 g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2893 return SCM_BOOL(SCM_REALPART (x
) < 0.0);
2899 SCM_GASSERT1 (SCM_BIGP (x
),
2900 g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2901 return SCM_BOOL(SCM_TYP16 (x
) == scm_tc16_bigneg
);
2904 SCM_GASSERT1 (SCM_INUMP (x
), g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2907 return SCM_BOOL(x
< SCM_INUM0
);
2911 SCM_GPROC1 (s_max
, "max", scm_tc7_asubr
, scm_max
, g_max
);
2914 scm_max (SCM x
, SCM y
)
2921 SCM_GASSERT0 (!SCM_UNBNDP (x
),
2922 g_max
, scm_makfrom0str (s_max
), SCM_WNA
, 0);
2923 SCM_GASSERT1 (SCM_NUMBERP (x
), g_max
, x
, SCM_ARG1
, s_max
);
2933 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARG1
, s_max
);
2938 return SCM_BIGSIGN (x
) ? y
: x
;
2939 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2941 return (1 == scm_bigcomp (x
, y
)) ? y
: x
;
2942 SCM_ASRTGO (SCM_REALP (y
), bady
);
2943 z
= scm_big2dbl (x
);
2944 return (z
< SCM_REALPART (y
)) ? y
: scm_makdbl (z
, 0.0);
2946 SCM_ASRTGO (SCM_REALP (x
), badx2
);
2948 SCM_GASSERT2 (SCM_REALP (x
),
2949 g_max
, x
, y
, SCM_ARG1
, s_max
);
2952 return ((SCM_REALPART (x
) < (z
= SCM_INUM (y
)))
2953 ? scm_makdbl (z
, 0.0)
2956 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2958 return ((SCM_REALPART (x
) < (z
= scm_big2dbl (y
)))
2959 ? scm_makdbl (z
, 0.0)
2961 SCM_ASRTGO (SCM_REALP (y
), bady
);
2963 SCM_ASRTGO (SCM_REALP (y
), bady
);
2965 return (SCM_REALPART (x
) < SCM_REALPART (y
)) ? y
: x
;
2970 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2972 return SCM_BIGSIGN (y
) ? x
: y
;
2973 if (!(SCM_REALP (y
)))
2976 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARGn
, s_max
);
2982 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARGn
, s_max
);
2985 return (((z
= SCM_INUM (x
)) < SCM_REALPART (y
))
2987 : scm_makdbl (z
, 0.0));
2993 SCM_GASSERT2 (SCM_BIGP (x
),
2994 g_max
, x
, y
, SCM_ARG1
, s_max
);
2996 return SCM_BIGSIGN (x
) ? y
: x
;
2997 SCM_ASRTGO (SCM_BIGP (y
), bady
);
2998 return (1 == scm_bigcomp (x
, y
)) ? y
: x
;
3005 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARGn
, s_max
);
3007 return SCM_BIGSIGN (y
) ? x
: y
;
3010 SCM_GASSERT2 (SCM_INUMP (x
), g_max
, x
, y
, SCM_ARG1
, s_max
);
3011 SCM_GASSERT2 (SCM_INUMP (y
), g_max
, x
, y
, SCM_ARGn
, s_max
);
3014 return ((long) x
< (long) y
) ? y
: x
;
3020 SCM_GPROC1 (s_min
, "min", scm_tc7_asubr
, scm_min
, g_min
);
3023 scm_min (SCM x
, SCM y
)
3030 SCM_GASSERT0 (!SCM_UNBNDP (x
),
3031 g_min
, scm_makfrom0str (s_min
), SCM_WNA
, 0);
3032 SCM_GASSERT1 (SCM_NUMBERP (x
), g_min
, x
, SCM_ARG1
, s_min
);
3042 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARG1
, s_min
);
3047 return SCM_BIGSIGN (x
) ? x
: y
;
3048 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3050 return (-1 == scm_bigcomp (x
, y
)) ? y
: x
;
3051 SCM_ASRTGO (SCM_REALP (y
), bady
);
3052 z
= scm_big2dbl (x
);
3053 return (z
> SCM_REALPART (y
)) ? y
: scm_makdbl (z
, 0.0);
3055 SCM_ASRTGO (SCM_REALP (x
), badx2
);
3057 SCM_GASSERT2 (SCM_REALP (x
),
3058 g_min
, x
, y
, SCM_ARG1
, s_min
);
3061 return ((SCM_REALPART (x
) > (z
= SCM_INUM (y
)))
3062 ? scm_makdbl (z
, 0.0)
3065 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3067 return ((SCM_REALPART (x
) > (z
= scm_big2dbl (y
)))
3068 ? scm_makdbl (z
, 0.0)
3070 SCM_ASRTGO (SCM_REALP (y
), bady
);
3072 SCM_ASRTGO (SCM_REALP (y
), bady
);
3074 return (SCM_REALPART (x
) > SCM_REALPART (y
)) ? y
: x
;
3079 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3081 return SCM_BIGSIGN (y
) ? y
: x
;
3082 if (!(SCM_REALP (y
)))
3085 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARGn
, s_min
);
3091 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARGn
, s_min
);
3094 return (((z
= SCM_INUM (x
)) > SCM_REALPART (y
))
3096 : scm_makdbl (z
, 0.0));
3102 SCM_GASSERT2 (SCM_BIGP (x
),
3103 g_min
, x
, y
, SCM_ARG1
, s_min
);
3105 return SCM_BIGSIGN (x
) ? x
: y
;
3106 SCM_ASRTGO (SCM_BIGP (y
), bady
);
3107 return (-1 == scm_bigcomp (x
, y
)) ? y
: x
;
3114 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARGn
, s_min
);
3116 return SCM_BIGSIGN (y
) ? y
: x
;
3119 SCM_GASSERT2 (SCM_INUMP (x
), g_min
, x
, y
, SCM_ARG1
, s_min
);
3120 SCM_GASSERT2 (SCM_INUMP (y
), g_min
, x
, y
, SCM_ARGn
, s_min
);
3123 return ((long) x
> (long) y
) ? y
: x
;
3129 SCM_GPROC1 (s_sum
, "+", scm_tc7_asubr
, scm_sum
, g_sum
);
3132 scm_sum (SCM x
, SCM y
)
3138 SCM_GASSERT1 (SCM_NUMBERP (x
), g_sum
, x
, SCM_ARG1
, s_sum
);
3149 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARG1
, s_sum
);
3160 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3163 if (SCM_NUMDIGS (x
) > SCM_NUMDIGS (y
))
3169 return scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3173 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3175 return scm_makdbl (scm_big2dbl (x
) + SCM_REALPART (y
),
3176 SCM_CPLXP (y
) ? SCM_IMAG (y
) : 0.0);
3178 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3180 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3190 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3198 else if (!SCM_INEXP (y
))
3201 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3207 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3216 return scm_makdbl (SCM_REALPART (x
) + SCM_REALPART (y
), i
);
3222 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3227 #ifndef SCM_DIGSTOOBIG
3228 long z
= scm_pseudolong (SCM_INUM (x
));
3229 return scm_addbig ((SCM_BIGDIG
*) & z
,
3231 (x
< 0) ? 0x0100 : 0,
3234 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3235 scm_longdigs (SCM_INUM (x
), zdigs
);
3236 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3241 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3243 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3246 return scm_makdbl (SCM_INUM (x
) + SCM_REALPART (y
),
3247 SCM_CPLXP (y
) ? SCM_IMAG (y
) : 0.0);
3254 SCM_ASRTGO (SCM_BIGP (x
), badx2
);
3262 SCM_ASRTGO (SCM_BIGP (y
), bady
);
3263 if (SCM_NUMDIGS (x
) > SCM_NUMDIGS (y
))
3269 return scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
), SCM_BIGSIGN (x
),
3277 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3281 #ifndef SCM_DIGSTOOBIG
3282 long z
= scm_pseudolong (SCM_INUM (x
));
3283 return scm_addbig (&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
3285 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3286 scm_longdigs (SCM_INUM (x
), zdigs
);
3287 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
3292 SCM_ASRTGO (SCM_INUMP (x
), badx2
);
3293 SCM_GASSERT2 (SCM_INUMP (y
), g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3296 x
= SCM_INUM (x
) + SCM_INUM (y
);
3297 if (SCM_FIXABLE (x
))
3298 return SCM_MAKINUM (x
);
3300 return scm_long2big (x
);
3303 return scm_makdbl ((double) x
, 0.0);
3305 scm_num_overflow (s_sum
);
3306 return SCM_UNSPECIFIED
;
3314 SCM_GPROC1 (s_difference
, "-", scm_tc7_asubr
, scm_difference
, g_difference
);
3317 scm_difference (SCM x
, SCM y
)
3322 if (!(SCM_NIMP (x
)))
3326 SCM_GASSERT0 (!SCM_UNBNDP (x
), g_difference
,
3327 scm_makfrom0str (s_difference
), SCM_WNA
, 0);
3329 SCM_WTA_DISPATCH_1 (g_difference
, x
, SCM_ARG1
, s_difference
);
3334 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARG1
, s_difference
);
3342 x
= scm_copybig (x
, !SCM_BIGSIGN (x
));
3343 return (SCM_NUMDIGS (x
) * SCM_BITSPERDIG
/ SCM_CHAR_BIT
3345 ? scm_big2inum (x
, SCM_NUMDIGS (x
))
3349 SCM_ASRTGO (SCM_INEXP (x
), badx
);
3350 return scm_makdbl (- SCM_REALPART (x
),
3351 SCM_CPLXP (x
) ? -SCM_IMAG (x
) : 0.0);
3354 return scm_sum (x
, SCM_MAKINUM (- SCM_INUM (y
)));
3356 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3360 return ((SCM_NUMDIGS (x
) < SCM_NUMDIGS (y
))
3361 ? scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3364 : scm_addbig (SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3365 SCM_BIGSIGN (y
) ^ 0x0100,
3367 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3368 return scm_makdbl (scm_big2dbl (x
) - SCM_REALPART (y
),
3369 SCM_CPLXP (y
) ? -SCM_IMAG (y
) : 0.0);
3371 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3373 return scm_makdbl (SCM_REALPART (x
) - scm_big2dbl (y
),
3374 SCM_CPLXP (x
) ? SCM_IMAG (x
) : 0.0);
3375 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3377 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3378 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3383 return scm_makdbl (SCM_REAL (x
) - SCM_REAL (y
),
3384 SCM_IMAG (x
) - SCM_IMAG (y
));
3386 return scm_makdbl (SCM_REAL (x
) - SCM_REALPART (y
), SCM_IMAG (x
));
3388 return scm_makdbl (SCM_REALPART (x
) - SCM_REALPART (y
),
3389 SCM_CPLXP (y
) ? - SCM_IMAG (y
) : 0.0);
3399 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3402 #ifndef SCM_DIGSTOOBIG
3403 long z
= scm_pseudolong (SCM_INUM (x
));
3404 return scm_addbig ((SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3405 (x
< 0) ? 0x0100 : 0,
3408 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3409 scm_longdigs (SCM_INUM (x
), zdigs
);
3410 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3417 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3423 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3426 return scm_makdbl (SCM_INUM (x
) - SCM_REALPART (y
),
3427 SCM_CPLXP (y
) ? -SCM_IMAG (y
) : 0.0);
3433 SCM_GASSERT2 (SCM_BIGP (x
),
3434 g_difference
, x
, y
, SCM_ARG1
, s_difference
);
3437 x
= scm_copybig (x
, !SCM_BIGSIGN (x
));
3438 return (SCM_NUMDIGS (x
) * SCM_BITSPERDIG
/ SCM_CHAR_BIT
3440 ? scm_big2inum (x
, SCM_NUMDIGS (x
))
3445 #ifndef SCM_DIGSTOOBIG
3446 long z
= scm_pseudolong (SCM_INUM (y
));
3447 return scm_addbig (&z
, SCM_DIGSPERLONG
, (y
< 0) ? 0 : 0x0100, x
, 0);
3449 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3450 scm_longdigs (SCM_INUM (x
), zdigs
);
3451 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (y
< 0) ? 0 : 0x0100,
3455 SCM_ASRTGO (SCM_BIGP (y
), bady
);
3456 return (SCM_NUMDIGS (x
) < SCM_NUMDIGS (y
)) ?
3457 scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
), SCM_BIGSIGN (x
),
3459 scm_addbig (SCM_BDIGITS (y
), SCM_NUMDIGS (y
), SCM_BIGSIGN (y
) ^ 0x0100,
3472 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3475 #ifndef SCM_DIGSTOOBIG
3476 long z
= scm_pseudolong (SCM_INUM (x
));
3477 return scm_addbig (&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3480 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3481 scm_longdigs (SCM_INUM (x
), zdigs
);
3482 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3488 SCM_GASSERT2 (SCM_INUMP (x
), g_difference
, x
, y
, SCM_ARG1
, s_difference
);
3494 SCM_GASSERT2 (SCM_INUMP (y
), g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3497 x
= SCM_INUM (x
) - SCM_INUM (y
);
3499 if (SCM_FIXABLE (x
))
3500 return SCM_MAKINUM (x
);
3502 return scm_long2big (x
);
3505 return scm_makdbl ((double) x
, 0.0);
3507 scm_num_overflow (s_difference
);
3508 return SCM_UNSPECIFIED
;
3516 SCM_GPROC1 (s_product
, "*", scm_tc7_asubr
, scm_product
, g_product
);
3519 scm_product (SCM x
, SCM y
)
3524 return SCM_MAKINUM (1L);
3525 SCM_GASSERT1 (SCM_NUMBERP (x
), g_product
, x
, SCM_ARG1
, s_product
);
3536 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARG1
, s_product
);
3547 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3549 return scm_mulbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3550 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3551 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
));
3552 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3555 double bg
= scm_big2dbl (x
);
3556 return scm_makdbl (bg
* SCM_REALPART (y
),
3557 SCM_CPLXP (y
) ? bg
* SCM_IMAG (y
) : 0.0);
3560 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3562 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3572 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3580 else if (!(SCM_INEXP (y
)))
3583 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARGn
, s_product
);
3589 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARGn
, s_product
);
3595 return scm_makdbl (SCM_REAL (x
) * SCM_REAL (y
)
3596 - SCM_IMAG (x
) * SCM_IMAG (y
),
3597 SCM_REAL (x
) * SCM_IMAG (y
)
3598 + SCM_IMAG (x
) * SCM_REAL (y
));
3600 return scm_makdbl (SCM_REAL (x
) * SCM_REALPART (y
),
3601 SCM_IMAG (x
) * SCM_REALPART (y
));
3603 return scm_makdbl (SCM_REALPART (x
) * SCM_REALPART (y
),
3605 ? SCM_REALPART (x
) * SCM_IMAG (y
)
3611 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3617 if (SCM_MAKINUM (1L) == x
)
3620 #ifndef SCM_DIGSTOOBIG
3621 long z
= scm_pseudolong (SCM_INUM (x
));
3622 return scm_mulbig ((SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3623 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3624 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3626 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3627 scm_longdigs (SCM_INUM (x
), zdigs
);
3628 return scm_mulbig (zdigs
, SCM_DIGSPERLONG
,
3629 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3630 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3634 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3636 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3639 return scm_makdbl (SCM_INUM (x
) * SCM_REALPART (y
),
3640 SCM_CPLXP (y
) ? SCM_INUM (x
) * SCM_IMAG (y
) : 0.0);
3646 SCM_ASRTGO (SCM_BIGP (x
), badx2
);
3654 SCM_ASRTGO (SCM_BIGP (y
), bady
);
3655 return scm_mulbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3656 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3657 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
));
3664 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARGn
, s_product
);
3669 if (SCM_MAKINUM (1L) == x
)
3672 #ifndef SCM_DIGSTOOBIG
3673 long z
= scm_pseudolong (SCM_INUM (x
));
3674 return scm_mulbig (&z
, SCM_DIGSPERLONG
,
3675 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3676 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3678 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3679 scm_longdigs (SCM_INUM (x
), zdigs
);
3680 return scm_mulbig (zdigs
, SCM_DIGSPERLONG
,
3681 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3682 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3687 SCM_ASRTGO (SCM_INUMP (x
), badx2
);
3688 SCM_GASSERT (SCM_INUMP (y
), g_product
, x
, y
, SCM_ARGn
, s_product
);
3698 y
= SCM_MAKINUM (k
);
3699 if (k
!= SCM_INUM (y
) || k
/ i
!= j
)
3702 int sgn
= (i
< 0) ^ (j
< 0);
3703 #ifndef SCM_DIGSTOOBIG
3704 i
= scm_pseudolong (i
);
3705 j
= scm_pseudolong (j
);
3706 return scm_mulbig ((SCM_BIGDIG
*) & i
, SCM_DIGSPERLONG
,
3707 (SCM_BIGDIG
*) & j
, SCM_DIGSPERLONG
, sgn
);
3708 #else /* SCM_DIGSTOOBIG */
3709 SCM_BIGDIG idigs
[SCM_DIGSPERLONG
];
3710 SCM_BIGDIG jdigs
[SCM_DIGSPERLONG
];
3711 scm_longdigs (i
, idigs
);
3712 scm_longdigs (j
, jdigs
);
3713 return scm_mulbig (idigs
, SCM_DIGSPERLONG
,
3714 jdigs
, SCM_DIGSPERLONG
,
3720 return scm_makdbl (((double) i
) * ((double) j
), 0.0);
3722 scm_num_overflow (s_product
);
3732 scm_num2dbl (SCM a
, const char *why
)
3735 return (double) SCM_INUM (a
);
3737 SCM_ASSERT (SCM_NIMP (a
), a
, "wrong type argument", why
);
3739 return (SCM_REALPART (a
));
3742 return scm_big2dbl (a
);
3744 SCM_ASSERT (0, a
, "wrong type argument", why
);
3745 return SCM_UNSPECIFIED
;
3749 SCM_GPROC1 (s_divide
, "/", scm_tc7_asubr
, scm_divide
, g_divide
);
3752 scm_divide (SCM x
, SCM y
)
3758 if (!(SCM_NIMP (x
)))
3762 SCM_GASSERT0 (!SCM_UNBNDP (x
),
3763 g_divide
, scm_makfrom0str (s_divide
), SCM_WNA
, 0);
3765 SCM_WTA_DISPATCH_1 (g_divide
, x
, SCM_ARG1
, s_divide
);
3770 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARG1
, s_divide
);
3777 return scm_makdbl (1.0 / scm_big2dbl (x
), 0.0);
3779 SCM_ASRTGO (SCM_INEXP (x
), badx
);
3781 return scm_makdbl (1.0 / SCM_REALPART (x
), 0.0);
3785 return scm_makdbl (r
/ d
, -i
/ d
);
3794 #ifndef SCM_RECKLESS
3796 scm_num_overflow (s_divide
);
3804 SCM w
= scm_copybig (x
, SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0));
3805 return (scm_divbigdig (SCM_BDIGITS (w
), SCM_NUMDIGS (w
),
3807 ? scm_makdbl (scm_big2dbl (x
) / SCM_INUM (y
), 0.0)
3810 #ifndef SCM_DIGSTOOBIG
3811 z
= scm_pseudolong (z
);
3812 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3813 (SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3814 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
3817 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3818 scm_longdigs (z
, zdigs
);
3819 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3820 zdigs
, SCM_DIGSPERLONG
,
3821 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
3824 return z
? z
: scm_makdbl (scm_big2dbl (x
) / SCM_INUM (y
), 0.0);
3826 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3829 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3830 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3831 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
), 3);
3832 return z
? z
: scm_makdbl (scm_big2dbl (x
) / scm_big2dbl (y
),
3835 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3837 return scm_makdbl (scm_big2dbl (x
) / SCM_REALPART (y
), 0.0);
3838 a
= scm_big2dbl (x
);
3842 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3849 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3852 d
= scm_big2dbl (y
);
3855 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3857 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3861 d
= SCM_REALPART (y
);
3863 return scm_makdbl (SCM_REALPART (x
) / d
,
3864 SCM_CPLXP (x
) ? SCM_IMAG (x
) / d
: 0.0);
3866 a
= SCM_REALPART (x
);
3872 return scm_makdbl ((a
* r
+ SCM_IMAG (x
) * i
) / d
,
3873 (SCM_IMAG (x
) * r
- a
* i
) / d
);
3877 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
3879 return scm_makdbl (1.0 / ((double) SCM_INUM (x
)), 0.0);
3884 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3886 return scm_makdbl (SCM_INUM (x
) / scm_big2dbl (y
), 0.0);
3887 if (!(SCM_INEXP (y
)))
3890 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARGn
, s_divide
);
3896 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARGn
, s_divide
);
3900 return scm_makdbl (SCM_INUM (x
) / SCM_REALPART (y
), 0.0);
3906 return scm_makdbl ((a
* r
) / d
, (-a
* i
) / d
);
3913 SCM_GASSERT2 (SCM_BIGP (x
),
3914 g_divide
, x
, y
, SCM_ARG1
, s_divide
);
3928 SCM w
= scm_copybig (x
, SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0));
3929 if (scm_divbigdig (SCM_BDIGITS (w
), SCM_NUMDIGS (w
),
3934 #ifndef SCM_DIGSTOOBIG
3935 z
= scm_pseudolong (z
);
3936 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3937 &z
, SCM_DIGSPERLONG
,
3938 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
3941 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3942 scm_longdigs (z
, zdigs
);
3943 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3944 zdigs
, SCM_DIGSPERLONG
,
3945 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
3951 SCM_ASRTGO (SCM_BIGP (y
), bady
);
3952 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3953 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3954 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
), 3);
3962 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
3971 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARGn
, s_divide
);
3976 SCM_GASSERT2 (SCM_INUMP (x
), g_divide
, x
, y
, SCM_ARG1
, s_divide
);
3979 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
3983 SCM_GASSERT2 (SCM_INUMP (y
), g_divide
, x
, y
, SCM_ARGn
, s_divide
);
3987 long z
= SCM_INUM (y
);
3988 if ((0 == z
) || SCM_INUM (x
) % z
)
3990 z
= SCM_INUM (x
) / z
;
3991 if (SCM_FIXABLE (z
))
3992 return SCM_MAKINUM (z
);
3994 return scm_long2big (z
);
3998 return scm_makdbl (((double) SCM_INUM (x
)) / ((double) SCM_INUM (y
)), 0.0);
4001 scm_num_overflow (s_divide
);
4002 return SCM_UNSPECIFIED
;
4011 SCM_GPROC1 (s_asinh
, "$asinh", scm_tc7_cxr
, (SCM (*)()) scm_asinh
, g_asinh
);
4014 scm_asinh (double x
)
4016 return log (x
+ sqrt (x
* x
+ 1));
4022 SCM_GPROC1 (s_acosh
, "$acosh", scm_tc7_cxr
, (SCM (*)()) scm_acosh
, g_acosh
);
4025 scm_acosh (double x
)
4027 return log (x
+ sqrt (x
* x
- 1));
4033 SCM_GPROC1 (s_atanh
, "$atanh", scm_tc7_cxr
, (SCM (*)()) scm_atanh
, g_atanh
);
4036 scm_atanh (double x
)
4038 return 0.5 * log ((1 + x
) / (1 - x
));
4044 SCM_GPROC1 (s_truncate
, "truncate", scm_tc7_cxr
, (SCM (*)()) scm_truncate
, g_truncate
);
4047 scm_truncate (double x
)
4056 SCM_GPROC1 (s_round
, "round", scm_tc7_cxr
, (SCM (*)()) scm_round
, g_round
);
4059 scm_round (double x
)
4061 double plus_half
= x
+ 0.5;
4062 double result
= floor (plus_half
);
4063 /* Adjust so that the scm_round is towards even. */
4064 return (plus_half
== result
&& plus_half
/ 2 != floor (plus_half
/ 2))
4065 ? result
- 1 : result
;
4070 SCM_GPROC1 (s_exact_to_inexact
, "exact->inexact", scm_tc7_cxr
, (SCM (*)()) scm_exact_to_inexact
, g_exact_to_inexact
);
4073 scm_exact_to_inexact (double z
)
4079 SCM_GPROC1 (s_i_floor
, "floor", scm_tc7_cxr
, (SCM (*)()) floor
, g_i_floor
);
4080 SCM_GPROC1 (s_i_ceil
, "ceiling", scm_tc7_cxr
, (SCM (*)()) ceil
, g_i_ceil
);
4081 SCM_GPROC1 (s_i_sqrt
, "$sqrt", scm_tc7_cxr
, (SCM (*)()) sqrt
, g_i_sqrt
);
4082 SCM_GPROC1 (s_i_abs
, "$abs", scm_tc7_cxr
, (SCM (*)()) fabs
, g_i_abs
);
4083 SCM_GPROC1 (s_i_exp
, "$exp", scm_tc7_cxr
, (SCM (*)()) exp
, g_i_exp
);
4084 SCM_GPROC1 (s_i_log
, "$log", scm_tc7_cxr
, (SCM (*)()) log
, g_i_log
);
4085 SCM_GPROC1 (s_i_sin
, "$sin", scm_tc7_cxr
, (SCM (*)()) sin
, g_i_sin
);
4086 SCM_GPROC1 (s_i_cos
, "$cos", scm_tc7_cxr
, (SCM (*)()) cos
, g_i_cos
);
4087 SCM_GPROC1 (s_i_tan
, "$tan", scm_tc7_cxr
, (SCM (*)()) tan
, g_i_tan
);
4088 SCM_GPROC1 (s_i_asin
, "$asin", scm_tc7_cxr
, (SCM (*)()) asin
, g_i_asin
);
4089 SCM_GPROC1 (s_i_acos
, "$acos", scm_tc7_cxr
, (SCM (*)()) acos
, g_i_acos
);
4090 SCM_GPROC1 (s_i_atan
, "$atan", scm_tc7_cxr
, (SCM (*)()) atan
, g_i_atan
);
4091 SCM_GPROC1 (s_i_sinh
, "$sinh", scm_tc7_cxr
, (SCM (*)()) sinh
, g_i_sinh
);
4092 SCM_GPROC1 (s_i_cosh
, "$cosh", scm_tc7_cxr
, (SCM (*)()) cosh
, g_i_cosh
);
4093 SCM_GPROC1 (s_i_tanh
, "$tanh", scm_tc7_cxr
, (SCM (*)()) tanh
, g_i_tanh
);
4100 static void scm_two_doubles (SCM z1
,
4102 const char *sstring
,
4106 scm_two_doubles (SCM z1
, SCM z2
, const char *sstring
, struct dpair
*xy
)
4109 xy
->x
= SCM_INUM (z1
);
4113 SCM_ASRTGO (SCM_NIMP (z1
), badz1
);
4115 xy
->x
= scm_big2dbl (z1
);
4118 #ifndef SCM_RECKLESS
4119 if (!SCM_REALP (z1
))
4120 badz1
:scm_wta (z1
, (char *) SCM_ARG1
, sstring
);
4122 xy
->x
= SCM_REALPART (z1
);
4126 SCM_ASSERT (SCM_REALP (z1
), z1
, SCM_ARG1
, sstring
);
4127 xy
->x
= SCM_REALPART (z1
);
4132 xy
->y
= SCM_INUM (z2
);
4136 SCM_ASRTGO (SCM_NIMP (z2
), badz2
);
4138 xy
->y
= scm_big2dbl (z2
);
4141 #ifndef SCM_RECKLESS
4142 if (!(SCM_REALP (z2
)))
4143 badz2
:scm_wta (z2
, (char *) SCM_ARG2
, sstring
);
4145 xy
->y
= SCM_REALPART (z2
);
4149 SCM_ASSERT (SCM_REALP (z2
), z2
, SCM_ARG2
, sstring
);
4150 xy
->y
= SCM_REALPART (z2
);
4159 SCM_DEFINE (scm_sys_expt
, "$expt", 2, 0, 0,
4162 #define FUNC_NAME s_scm_sys_expt
4165 scm_two_doubles (z1
, z2
, FUNC_NAME
, &xy
);
4166 return scm_makdbl (pow (xy
.x
, xy
.y
), 0.0);
4172 SCM_DEFINE (scm_sys_atan2
, "$atan2", 2, 0, 0,
4175 #define FUNC_NAME s_scm_sys_atan2
4178 scm_two_doubles (z1
, z2
, FUNC_NAME
, &xy
);
4179 return scm_makdbl (atan2 (xy
.x
, xy
.y
), 0.0);
4185 SCM_DEFINE (scm_make_rectangular
, "make-rectangular", 2, 0, 0,
4188 #define FUNC_NAME s_scm_make_rectangular
4191 scm_two_doubles (z1
, z2
, FUNC_NAME
, &xy
);
4192 return scm_makdbl (xy
.x
, xy
.y
);
4198 SCM_DEFINE (scm_make_polar
, "make-polar", 2, 0, 0,
4201 #define FUNC_NAME s_scm_make_polar
4204 scm_two_doubles (z1
, z2
, FUNC_NAME
, &xy
);
4205 return scm_makdbl (xy
.x
* cos (xy
.y
), xy
.x
* sin (xy
.y
));
4212 SCM_GPROC (s_real_part
, "real-part", 1, 0, 0, scm_real_part
, g_real_part
);
4215 scm_real_part (SCM z
)
4220 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4223 if (!(SCM_INEXP (z
)))
4226 SCM_WTA_DISPATCH_1 (g_real_part
, z
, SCM_ARG1
, s_real_part
);
4229 SCM_GASSERT1 (SCM_INEXP (z
),
4230 g_real_part
, z
, SCM_ARG1
, s_real_part
);
4233 return scm_makdbl (SCM_REAL (z
), 0.0);
4240 SCM_GPROC (s_imag_part
, "imag-part", 1, 0, 0, scm_imag_part
, g_imag_part
);
4243 scm_imag_part (SCM z
)
4248 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4251 if (!(SCM_INEXP (z
)))
4254 SCM_WTA_DISPATCH_1 (g_imag_part
, z
, SCM_ARG1
, s_imag_part
);
4257 SCM_GASSERT1 (SCM_INEXP (z
),
4258 g_imag_part
, z
, SCM_ARG1
, s_imag_part
);
4261 return scm_makdbl (SCM_IMAG (z
), 0.0);
4267 SCM_GPROC (s_magnitude
, "magnitude", 1, 0, 0, scm_magnitude
, g_magnitude
);
4270 scm_magnitude (SCM z
)
4275 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4278 if (!(SCM_INEXP (z
)))
4281 SCM_WTA_DISPATCH_1 (g_magnitude
, z
, SCM_ARG1
, s_magnitude
);
4284 SCM_GASSERT1 (SCM_INEXP (z
),
4285 g_magnitude
, z
, SCM_ARG1
, s_magnitude
);
4289 double i
= SCM_IMAG (z
), r
= SCM_REAL (z
);
4290 return scm_makdbl (sqrt (i
* i
+ r
* r
), 0.0);
4292 return scm_makdbl (fabs (SCM_REALPART (z
)), 0.0);
4298 SCM_GPROC (s_angle
, "angle", 1, 0, 0, scm_angle
, g_angle
);
4306 x
= (z
>= SCM_INUM0
) ? 1.0 : -1.0;
4310 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4313 x
= (SCM_TYP16 (z
) == scm_tc16_bigpos
) ? 1.0 : -1.0;
4316 if (!(SCM_INEXP (z
)))
4319 SCM_WTA_DISPATCH_1 (g_angle
, z
, SCM_ARG1
, s_angle
);
4322 SCM_GASSERT1 (SCM_INEXP (z
), g_angle
, z
, SCM_ARG1
, s_angle
);
4326 x
= SCM_REALPART (z
);
4332 return scm_makdbl (atan2 (y
, x
), 0.0);
4336 SCM_DEFINE (scm_inexact_to_exact
, "inexact->exact", 1, 0, 0,
4339 #define FUNC_NAME s_scm_inexact_to_exact
4344 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4347 #ifndef SCM_RECKLESS
4348 if (!(SCM_REALP (z
)))
4355 SCM_VALIDATE_REAL (1,z
);
4359 double u
= floor (SCM_REALPART (z
) + 0.5);
4360 if ((u
<= SCM_MOST_POSITIVE_FIXNUM
) && (-u
<= -SCM_MOST_NEGATIVE_FIXNUM
))
4362 /* Negation is a workaround for HP700 cc bug */
4363 SCM ans
= SCM_MAKINUM ((long) u
);
4364 if (SCM_INUM (ans
) == (long) u
)
4367 SCM_ASRTGO (isfinite (u
), badz
); /* problem? */
4368 return scm_dbl2big (u
);
4371 return SCM_MAKINUM ((long) floor (SCM_REALPART (z
) + 0.5));
4378 #else /* ~SCM_FLOATS */
4379 SCM_GPROC (s_trunc
, "truncate", 1, 0, 0, scm_trunc
, g_trunc
);
4384 SCM_GASSERT2 (SCM_INUMP (x
), g_trunc
, x
, y
, SCM_ARG1
, s_truncate
);
4390 #endif /* SCM_FLOATS */
4394 /* d must be integer */
4397 scm_dbl2big (double d
)
4403 double u
= (d
< 0) ? -d
: d
;
4404 while (0 != floor (u
))
4409 ans
= scm_mkbig (i
, d
< 0);
4410 digits
= SCM_BDIGITS (ans
);
4418 #ifndef SCM_RECKLESS
4420 scm_num_overflow ("dbl2big");
4431 scm_sizet i
= SCM_NUMDIGS (b
);
4432 SCM_BIGDIG
*digits
= SCM_BDIGITS (b
);
4434 ans
= digits
[i
] + SCM_BIGRAD
* ans
;
4435 if (scm_tc16_bigneg
== SCM_TYP16 (b
))
4444 scm_long2num (long sl
)
4446 if (!SCM_FIXABLE (sl
))
4449 return scm_long2big (sl
);
4452 return scm_makdbl ((double) sl
, 0.0);
4458 return SCM_MAKINUM (sl
);
4462 #ifdef HAVE_LONG_LONGS
4465 scm_long_long2num (long_long sl
)
4467 if (!SCM_FIXABLE (sl
))
4470 return scm_long_long2big (sl
);
4473 return scm_makdbl ((double) sl
, 0.0);
4479 return SCM_MAKINUM (sl
);
4486 scm_ulong2num (unsigned long sl
)
4488 if (!SCM_POSFIXABLE (sl
))
4491 return scm_ulong2big (sl
);
4494 return scm_makdbl ((double) sl
, 0.0);
4500 return SCM_MAKINUM (sl
);
4505 scm_num2long (SCM num
, char *pos
, const char *s_caller
)
4509 if (SCM_INUMP (num
))
4511 res
= SCM_INUM (num
);
4514 SCM_ASRTGO (SCM_NIMP (num
), wrong_type_arg
);
4516 if (SCM_REALP (num
))
4518 volatile double u
= SCM_REALPART (num
);
4529 unsigned long oldres
= 0;
4531 /* can't use res directly in case num is -2^31. */
4532 unsigned long pos_res
= 0;
4534 for (l
= SCM_NUMDIGS (num
); l
--;)
4536 pos_res
= SCM_BIGUP (pos_res
) + SCM_BDIGITS (num
)[l
];
4537 /* check for overflow. */
4538 if (pos_res
< oldres
)
4542 if (SCM_TYP16 (num
) == scm_tc16_bigpos
)
4558 scm_wrong_type_arg (s_caller
, (int) pos
, num
);
4560 scm_out_of_range (s_caller
, num
);
4565 #ifdef HAVE_LONG_LONGS
4568 scm_num2long_long (SCM num
, char *pos
, const char *s_caller
)
4572 if (SCM_INUMP (num
))
4574 res
= SCM_INUM (num
);
4577 SCM_ASRTGO (SCM_NIMP (num
), wrong_type_arg
);
4579 if (SCM_REALP (num
))
4581 double u
= SCM_REALPART (num
);
4584 if ((res
< 0 && u
> 0) || (res
> 0 && u
< 0)) /* check for overflow. */
4593 unsigned long long oldres
= 0;
4595 /* can't use res directly in case num is -2^63. */
4596 unsigned long long pos_res
= 0;
4598 for (l
= SCM_NUMDIGS (num
); l
--;)
4600 pos_res
= SCM_LONGLONGBIGUP (pos_res
) + SCM_BDIGITS (num
)[l
];
4601 /* check for overflow. */
4602 if (pos_res
< oldres
)
4606 if (SCM_TYP16 (num
) == scm_tc16_bigpos
)
4622 scm_wrong_type_arg (s_caller
, (int) pos
, num
);
4624 scm_out_of_range (s_caller
, num
);
4631 scm_num2ulong (SCM num
, char *pos
, const char *s_caller
)
4635 if (SCM_INUMP (num
))
4637 if (SCM_INUM (num
) < 0)
4639 res
= SCM_INUM (num
);
4642 SCM_ASRTGO (SCM_NIMP (num
), wrong_type_arg
);
4644 if (SCM_REALP (num
))
4646 double u
= SCM_REALPART (num
);
4657 unsigned long oldres
= 0;
4661 for (l
= SCM_NUMDIGS (num
); l
--;)
4663 res
= SCM_BIGUP (res
) + SCM_BDIGITS (num
)[l
];
4672 scm_wrong_type_arg (s_caller
, (int) pos
, num
);
4674 scm_out_of_range (s_caller
, num
);
4681 add1 (double f
, double *fsum
)
4693 scm_add_feature("complex");
4695 scm_add_feature("inexact");
4697 SCM_NEWSMOB(scm_flo0
,scm_tc_flo
,NULL
);
4699 SCM_NEWSMOB(scm_flo0
,scm_tc_dblr
,scm_must_malloc (1L * sizeof (double), "real"));
4700 SCM_REAL (scm_flo0
) = 0.0;
4703 scm_dblprec
= (DBL_DIG
> 20) ? 20 : DBL_DIG
;
4705 { /* determine floating point precision */
4707 double fsum
= 1.0 + f
;
4711 if (++scm_dblprec
> 20)
4715 scm_dblprec
= scm_dblprec
- 1;
4717 #endif /* DBL_DIG */
4719 #include "numbers.x"