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 */
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
);
158 SCM_GASSERT1 (SCM_BIGP (x
), g_abs
, x
, SCM_ARG1
, s_abs
);
159 if (SCM_TYP16 (x
) == scm_tc16_bigpos
)
161 return scm_copybig (x
, 0);
164 SCM_GASSERT1 (SCM_INUMP (x
), g_abs
, x
, SCM_ARG1
, s_abs
);
166 if (SCM_INUM (x
) >= 0)
169 if (!SCM_POSFIXABLE (cx
))
171 return scm_long2big (cx
);
173 scm_num_overflow (s_abs
);
175 return SCM_MAKINUM (cx
);
178 SCM_GPROC (s_quotient
, "quotient", 2, 0, 0, scm_quotient
, g_quotient
);
181 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 SCM sw
= scm_copybig (x
, SCM_BIGSIGN (x
) ? (SCM_ASWORD (y
) > 0) : (SCM_ASWORD (y
) < 0));
205 scm_divbigdig (SCM_BDIGITS (sw
), SCM_NUMDIGS (sw
), (SCM_BIGDIG
) z
);
206 return scm_normbig (sw
);
209 #ifndef SCM_DIGSTOOBIG
210 long w
= scm_pseudolong (z
);
211 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
212 (SCM_BIGDIG
*) & w
, SCM_DIGSPERLONG
,
213 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
)
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
))
404 SCM t
= scm_remainder (x
, y
);
412 y
= scm_remainder (y
, x
);
415 /* instead of the switch, we could just
416 return scm_gcd (y, scm_modulo (x, y)); */
430 SCM_GASSERT2 (SCM_INUMP (x
), g_gcd
, x
, y
, SCM_ARG1
, s_gcd
);
431 SCM_GASSERT2 (SCM_INUMP (y
), g_gcd
, x
, y
, SCM_ARGn
, s_gcd
);
446 for (k
= 1; !(1 & ((int) u
| (int) v
)); k
<<= 1, u
>>= 1, v
>>= 1);
465 if (!SCM_POSFIXABLE (u
))
467 return scm_long2big (u
);
469 scm_num_overflow (s_gcd
);
471 return SCM_MAKINUM (u
);
474 SCM_GPROC1 (s_lcm
, "lcm", scm_tc7_asubr
, scm_lcm
, g_lcm
);
477 scm_lcm (SCM n1
, SCM n2
)
481 SCM_GASSERT2 (SCM_INUMP (n1
) || SCM_UNBNDP (n1
),
482 g_lcm
, n1
, n2
, SCM_ARG1
, s_lcm
);
483 SCM_GASSERT2 (SCM_INUMP (n2
) || SCM_UNBNDP (n2
),
484 g_lcm
, n1
, n2
, SCM_ARGn
, s_lcm
);
486 SCM_GASSERT2 (SCM_INUMP (n1
)
489 g_lcm
, n1
, n2
, SCM_ARG1
, s_lcm
);
490 SCM_GASSERT2 (SCM_INUMP (n2
)
493 g_lcm
, n1
, n2
, SCM_ARGn
, s_lcm
);
497 n2
= SCM_MAKINUM (1L);
502 d
= scm_gcd (n1
, n2
);
505 return scm_abs (scm_product (n1
, scm_quotient (n2
, d
)));
510 #define scm_long2num SCM_MAKINUM
515 #define SCM_LOGOP_RETURN(x) scm_ulong2num(x)
517 #define SCM_LOGOP_RETURN(x) SCM_MAKINUM(x)
520 SCM_DEFINE1 (scm_logand
, "logand", scm_tc7_asubr
,
522 "Returns the integer which is the bit-wise AND of the two integer\n"
526 "(number->string (logand #b1100 #b1010) 2)\n"
527 " @result{} \"1000\"")
528 #define FUNC_NAME s_scm_logand
534 return SCM_MAKINUM (-1);
537 SCM_VALIDATE_LONG_COPY (1,n1
,i1
);
538 SCM_VALIDATE_LONG_COPY (2,n2
,i2
);
539 return SCM_LOGOP_RETURN (i1
& i2
);
543 SCM_DEFINE1 (scm_logior
, "logior", scm_tc7_asubr
,
545 "Returns the integer which is the bit-wise OR of the two integer\n"
549 "(number->string (logior #b1100 #b1010) 2)\n"
550 " @result{} \"1110\"\n"
552 #define FUNC_NAME s_scm_logior
561 SCM_VALIDATE_LONG_COPY (1,n1
,i1
);
562 SCM_VALIDATE_LONG_COPY (2,n2
,i2
);
563 return SCM_LOGOP_RETURN (i1
| i2
);
567 SCM_DEFINE1 (scm_logxor
, "logxor", scm_tc7_asubr
,
569 "Returns the integer which is the bit-wise XOR of the two integer\n"
573 "(number->string (logxor #b1100 #b1010) 2)\n"
574 " @result{} \"110\"\n"
576 #define FUNC_NAME s_scm_logxor
585 SCM_VALIDATE_LONG_COPY (1,n1
,i1
);
586 SCM_VALIDATE_LONG_COPY (2,n2
,i2
);
587 return SCM_LOGOP_RETURN (i1
^ i2
);
591 SCM_DEFINE (scm_logtest
, "logtest", 2, 0, 0,
594 "(logtest j k) @equiv{} (not (zero? (logand j k)))\n\n"
595 "(logtest #b0100 #b1011) @result{} #f\n"
596 "(logtest #b0100 #b0111) @result{} #t\n"
598 #define FUNC_NAME s_scm_logtest
601 SCM_VALIDATE_LONG_COPY (1,n1
,i1
);
602 SCM_VALIDATE_LONG_COPY (2,n2
,i2
);
603 return SCM_BOOL(i1
& i2
);
608 SCM_DEFINE (scm_logbit_p
, "logbit?", 2, 0, 0,
611 "(logbit? index j) @equiv{} (logtest (integer-expt 2 index) j)\n\n"
612 "(logbit? 0 #b1101) @result{} #t\n"
613 "(logbit? 1 #b1101) @result{} #f\n"
614 "(logbit? 2 #b1101) @result{} #t\n"
615 "(logbit? 3 #b1101) @result{} #t\n"
616 "(logbit? 4 #b1101) @result{} #f\n"
618 #define FUNC_NAME s_scm_logbit_p
621 SCM_VALIDATE_INUM_MIN_COPY (1,index
,0,i1
);
622 SCM_VALIDATE_LONG_COPY (2,j
,i2
);
623 return SCM_BOOL((1 << i1
) & i2
);
627 SCM_DEFINE (scm_lognot
, "lognot", 1, 0, 0,
629 "Returns the integer which is the 2s-complement of the integer argument.\n\n"
632 "(number->string (lognot #b10000000) 2)\n"
633 " @result{} \"-10000001\"\n"
634 "(number->string (lognot #b0) 2)\n"
635 " @result{} \"-1\"\n"
638 #define FUNC_NAME s_scm_lognot
640 SCM_VALIDATE_INUM (1,n
);
641 return scm_difference (SCM_MAKINUM (-1L), n
);
645 SCM_DEFINE (scm_integer_expt
, "integer-expt", 2, 0, 0,
647 "Returns @var{n} raised to the non-negative integer exponent @var{k}.\n\n"
650 "(integer-expt 2 5)\n"
652 "(integer-expt -3 3)\n"
655 #define FUNC_NAME s_scm_integer_expt
657 SCM acc
= SCM_MAKINUM (1L);
660 if (SCM_INUM0
== n
|| acc
== n
)
662 else if (SCM_MAKINUM (-1L) == n
)
663 return SCM_BOOL_F
== scm_even_p (k
) ? n
: acc
;
665 SCM_VALIDATE_ULONG_COPY (2,k
,i2
);
669 n
= scm_divide (n
, SCM_UNDEFINED
);
676 return scm_product (acc
, n
);
678 acc
= scm_product (acc
, n
);
679 n
= scm_product (n
, n
);
685 SCM_DEFINE (scm_ash
, "ash", 2, 0, 0,
687 "Returns an integer equivalent to\n"
688 "@code{(inexact->exact (floor (* @var{int} (expt 2 @var{count}))))}.@refill\n\n"
691 "(number->string (ash #b1 3) 2)\n"
692 " @result{} \"1000\""
693 "(number->string (ash #b1010 -1) 2)"
696 #define FUNC_NAME s_scm_ash
698 /* GJB:FIXME:: what is going on here? */
699 SCM res
= SCM_ASSCM (SCM_INUM (n
));
700 SCM_VALIDATE_INUM (2,cnt
);
704 res
= scm_integer_expt (SCM_MAKINUM (2), SCM_MAKINUM (-SCM_INUM (cnt
)));
705 if (SCM_NFALSEP (scm_negative_p (n
)))
706 return scm_sum (SCM_MAKINUM (-1L),
707 scm_quotient (scm_sum (SCM_MAKINUM (1L), n
), res
));
709 return scm_quotient (n
, res
);
712 return scm_product (n
, scm_integer_expt (SCM_MAKINUM (2), cnt
));
714 SCM_VALIDATE_INUM (1,n
)
715 cnt
= SCM_INUM (cnt
);
717 return SCM_MAKINUM (SCM_SRS (res
, -cnt
));
718 res
= SCM_MAKINUM (res
<< cnt
);
719 if (SCM_INUM (res
) >> cnt
!= SCM_INUM (n
))
720 scm_num_overflow (FUNC_NAME
);
726 /* GJB:FIXME: do not use SCMs as integers! */
727 SCM_DEFINE (scm_bit_extract
, "bit-extract", 3, 0, 0,
728 (SCM n
, SCM start
, SCM end
),
729 "Returns the integer composed of the @var{start} (inclusive) through\n"
730 "@var{end} (exclusive) bits of @var{n}. The @var{start}th bit becomes\n"
731 "the 0-th bit in the result.@refill\n\n"
734 "(number->string (bit-extract #b1101101010 0 4) 2)\n"
735 " @result{} \"1010\"\n"
736 "(number->string (bit-extract #b1101101010 4 9) 2)\n"
737 " @result{} \"10110\"\n"
739 #define FUNC_NAME s_scm_bit_extract
742 SCM_VALIDATE_INUM (1,n
);
743 SCM_VALIDATE_INUM_MIN_COPY (2,start
,0,istart
);
744 SCM_VALIDATE_INUM_MIN_COPY (3, end
, 0, iend
);
745 SCM_ASSERT_RANGE (3, end
, (iend
>= istart
));
749 scm_logand (scm_difference (scm_integer_expt (SCM_MAKINUM (2),
750 SCM_MAKINUM (iend
- istart
)),
752 scm_ash (n
, SCM_MAKINUM (-istart
)));
754 SCM_VALIDATE_INUM (1,n
);
756 return SCM_MAKINUM ((SCM_INUM (n
) >> istart
) & ((1L << (iend
- istart
)) - 1));
760 static const char scm_logtab
[] = {
761 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
764 SCM_DEFINE (scm_logcount
, "logcount", 1, 0, 0,
766 "Returns the number of bits in integer @var{n}. If integer is positive,\n"
767 "the 1-bits in its binary representation are counted. If negative, the\n"
768 "0-bits in its two's-complement binary representation are counted. If 0,\n"
772 "(logcount #b10101010)\n"
779 #define FUNC_NAME s_scm_logcount
781 register unsigned long c
= 0;
788 SCM_VALIDATE_BIGINT (1,n
);
790 return scm_logcount (scm_difference (SCM_MAKINUM (-1L), n
));
791 ds
= SCM_BDIGITS (n
);
792 for (i
= SCM_NUMDIGS (n
); i
--;)
793 for (d
= ds
[i
]; d
; d
>>= 4)
794 c
+= scm_logtab
[15 & d
];
795 return SCM_MAKINUM (c
);
798 SCM_VALIDATE_INUM (1,n
);
800 if ((nn
= SCM_INUM (n
)) < 0)
803 c
+= scm_logtab
[15 & nn
];
804 return SCM_MAKINUM (c
);
809 static const char scm_ilentab
[] = {
810 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
813 SCM_DEFINE (scm_integer_length
, "integer-length", 1, 0, 0,
815 "Returns the number of bits neccessary to represent @var{n}.\n\n"
818 "(integer-length #b10101010)\n"
820 "(integer-length 0)\n"
822 "(integer-length #b1111)\n"
825 #define FUNC_NAME s_scm_integer_length
827 register unsigned long c
= 0;
834 SCM_VALIDATE_BIGINT (1,n
);
836 return scm_integer_length (scm_difference (SCM_MAKINUM (-1L), n
));
837 ds
= SCM_BDIGITS (n
);
838 d
= ds
[c
= SCM_NUMDIGS (n
) - 1];
839 for (c
*= SCM_BITSPERDIG
; d
; d
>>= 4)
842 l
= scm_ilentab
[15 & d
];
844 return SCM_MAKINUM (c
- 4 + l
);
847 SCM_VALIDATE_INUM (1,n
);
849 if ((nn
= SCM_INUM (n
)) < 0)
854 l
= scm_ilentab
[15 & nn
];
856 return SCM_MAKINUM (c
- 4 + l
);
862 static const char s_bignum
[] = "bignum";
865 scm_mkbig (scm_sizet nlen
, int sign
)
868 /* Cast to long int to avoid signed/unsigned comparison warnings. */
869 if ((( ((long int)nlen
) << 16) >> 16) != (long int) nlen
)
870 scm_wta (SCM_MAKINUM (nlen
), (char *) SCM_NALLOC
, s_bignum
);
874 SCM_SETCHARS (v
, scm_must_malloc ((long) (nlen
* sizeof (SCM_BIGDIG
)),
876 SCM_SETNUMDIGS (v
, nlen
, sign
? scm_tc16_bigneg
: scm_tc16_bigpos
);
883 scm_big2inum (SCM b
, scm_sizet l
)
885 unsigned long num
= 0;
886 SCM_BIGDIG
*tmp
= SCM_BDIGITS (b
);
888 num
= SCM_BIGUP (num
) + tmp
[l
];
889 if (SCM_TYP16 (b
) == scm_tc16_bigpos
)
891 if (SCM_POSFIXABLE (num
))
892 return SCM_MAKINUM (num
);
894 else if (SCM_UNEGFIXABLE (num
))
895 return SCM_MAKINUM (-num
);
900 static const char s_adjbig
[] = "scm_adjbig";
903 scm_adjbig (SCM b
, scm_sizet nlen
)
905 scm_sizet nsiz
= nlen
;
906 if (((nsiz
<< 16) >> 16) != nlen
)
907 scm_wta (scm_ulong2num (nsiz
), (char *) SCM_NALLOC
, s_adjbig
);
913 scm_must_realloc ((char *) SCM_CHARS (b
),
914 (long) (SCM_NUMDIGS (b
) * sizeof (SCM_BIGDIG
)),
915 (long) (nsiz
* sizeof (SCM_BIGDIG
)), s_adjbig
));
917 SCM_SETCHARS (b
, digits
);
918 SCM_SETNUMDIGS (b
, nsiz
, SCM_TYP16 (b
));
930 scm_sizet nlen
= SCM_NUMDIGS (b
);
932 int nlen
= SCM_NUMDIGS (b
); /* unsigned nlen breaks on Cray when nlen => 0 */
934 SCM_BIGDIG
*zds
= SCM_BDIGITS (b
);
935 while (nlen
-- && !zds
[nlen
]);
937 if (nlen
* SCM_BITSPERDIG
/ SCM_CHAR_BIT
<= sizeof (SCM
))
938 if (SCM_INUMP (b
= scm_big2inum (b
, (scm_sizet
) nlen
)))
940 if (SCM_NUMDIGS (b
) == nlen
)
942 return scm_adjbig (b
, (scm_sizet
) nlen
);
948 scm_copybig (SCM b
, int sign
)
950 scm_sizet i
= SCM_NUMDIGS (b
);
951 SCM ans
= scm_mkbig (i
, sign
);
952 SCM_BIGDIG
*src
= SCM_BDIGITS (b
), *dst
= SCM_BDIGITS (ans
);
961 scm_long2big (long n
)
965 SCM ans
= scm_mkbig (SCM_DIGSPERLONG
, n
< 0);
966 digits
= SCM_BDIGITS (ans
);
969 while (i
< SCM_DIGSPERLONG
)
971 digits
[i
++] = SCM_BIGLO (n
);
972 n
= SCM_BIGDN ((unsigned long) n
);
977 #ifdef HAVE_LONG_LONGS
980 scm_long_long2big (long_long n
)
990 if ((long long) tn
== n
)
991 return scm_long2big (tn
);
997 for (tn
= n
, n_digits
= 0;
999 ++n_digits
, tn
= SCM_BIGDN ((ulong_long
) tn
))
1004 ans
= scm_mkbig (n_digits
, n
< 0);
1005 digits
= SCM_BDIGITS (ans
);
1008 while (i
< n_digits
)
1010 digits
[i
++] = SCM_BIGLO (n
);
1011 n
= SCM_BIGDN ((ulong_long
) n
);
1019 scm_2ulong2big (unsigned long *np
)
1026 ans
= scm_mkbig (2 * SCM_DIGSPERLONG
, 0);
1027 digits
= SCM_BDIGITS (ans
);
1030 for (i
= 0; i
< SCM_DIGSPERLONG
; ++i
)
1032 digits
[i
] = SCM_BIGLO (n
);
1033 n
= SCM_BIGDN ((unsigned long) n
);
1036 for (i
= 0; i
< SCM_DIGSPERLONG
; ++i
)
1038 digits
[i
+ SCM_DIGSPERLONG
] = SCM_BIGLO (n
);
1039 n
= SCM_BIGDN ((unsigned long) n
);
1047 scm_ulong2big (unsigned long n
)
1051 SCM ans
= scm_mkbig (SCM_DIGSPERLONG
, 0);
1052 digits
= SCM_BDIGITS (ans
);
1053 while (i
< SCM_DIGSPERLONG
)
1055 digits
[i
++] = SCM_BIGLO (n
);
1064 scm_bigcomp (SCM x
, SCM y
)
1066 int xsign
= SCM_BIGSIGN (x
);
1067 int ysign
= SCM_BIGSIGN (y
);
1068 scm_sizet xlen
, ylen
;
1070 /* Look at the signs, first. */
1076 /* They're the same sign, so see which one has more digits. Note
1077 that, if they are negative, the longer number is the lesser. */
1078 ylen
= SCM_NUMDIGS (y
);
1079 xlen
= SCM_NUMDIGS (x
);
1081 return (xsign
) ? -1 : 1;
1083 return (xsign
) ? 1 : -1;
1085 /* They have the same number of digits, so find the most significant
1086 digit where they differ. */
1090 if (SCM_BDIGITS (y
)[xlen
] != SCM_BDIGITS (x
)[xlen
])
1091 /* Make the discrimination based on the digit that differs. */
1092 return ((SCM_BDIGITS (y
)[xlen
] > SCM_BDIGITS (x
)[xlen
])
1094 : (xsign
? 1 : -1));
1097 /* The numbers are identical. */
1101 #ifndef SCM_DIGSTOOBIG
1105 scm_pseudolong (long x
)
1110 SCM_BIGDIG bd
[SCM_DIGSPERLONG
];
1116 while (i
< SCM_DIGSPERLONG
)
1118 p
.bd
[i
++] = SCM_BIGLO (x
);
1121 /* p.bd[0] = SCM_BIGLO(x); p.bd[1] = SCM_BIGDN(x); */
1129 scm_longdigs (long x
, SCM_BIGDIG digs
[])
1134 while (i
< SCM_DIGSPERLONG
)
1136 digs
[i
++] = SCM_BIGLO (x
);
1145 scm_addbig (SCM_BIGDIG
*x
, scm_sizet nx
, int xsgn
, SCM bigy
, int sgny
)
1147 /* Assumes nx <= SCM_NUMDIGS(bigy) */
1148 /* Assumes xsgn and sgny scm_equal either 0 or 0x0100 */
1150 scm_sizet i
= 0, ny
= SCM_NUMDIGS (bigy
);
1151 SCM z
= scm_copybig (bigy
, SCM_BIGSIGN (bigy
) ^ sgny
);
1152 SCM_BIGDIG
*zds
= SCM_BDIGITS (z
);
1153 if (xsgn
^ SCM_BIGSIGN (z
))
1157 num
+= (long) zds
[i
] - x
[i
];
1160 zds
[i
] = num
+ SCM_BIGRAD
;
1165 zds
[i
] = SCM_BIGLO (num
);
1170 if (num
&& nx
== ny
)
1174 SCM_SETCAR (z
, SCM_CARW (z
) ^ 0x0100);
1177 num
+= (SCM_BIGRAD
- 1) - zds
[i
];
1178 zds
[i
++] = SCM_BIGLO (num
);
1179 num
= SCM_BIGDN (num
);
1189 zds
[i
++] = num
+ SCM_BIGRAD
;
1194 zds
[i
++] = SCM_BIGLO (num
);
1203 num
+= (long) zds
[i
] + x
[i
];
1204 zds
[i
++] = SCM_BIGLO (num
);
1205 num
= SCM_BIGDN (num
);
1213 zds
[i
++] = SCM_BIGLO (num
);
1214 num
= SCM_BIGDN (num
);
1220 z
= scm_adjbig (z
, ny
+ 1);
1221 SCM_BDIGITS (z
)[ny
] = num
;
1225 return scm_normbig (z
);
1230 scm_mulbig (SCM_BIGDIG
*x
, scm_sizet nx
, SCM_BIGDIG
*y
, scm_sizet ny
, int sgn
)
1232 scm_sizet i
= 0, j
= nx
+ ny
;
1233 unsigned long n
= 0;
1234 SCM z
= scm_mkbig (j
, sgn
);
1235 SCM_BIGDIG
*zds
= SCM_BDIGITS (z
);
1245 n
+= zds
[i
+ j
] + ((unsigned long) x
[i
] * y
[j
]);
1246 zds
[i
+ j
++] = SCM_BIGLO (n
);
1258 return scm_normbig (z
);
1262 /* Sun's compiler complains about the fact that this function has an
1263 ANSI prototype in numbers.h, but a K&R declaration here, and the
1264 two specify different promotions for the third argument. I'm going
1265 to turn this into an ANSI declaration, and see if anyone complains
1266 about it not being K&R. */
1269 scm_divbigdig (SCM_BIGDIG
* ds
,
1273 register unsigned long t2
= 0;
1276 t2
= SCM_BIGUP (t2
) + ds
[h
];
1286 scm_divbigint (SCM x
, long z
, int sgn
, int mode
)
1292 register unsigned long t2
= 0;
1293 register SCM_BIGDIG
*ds
= SCM_BDIGITS (x
);
1294 scm_sizet nd
= SCM_NUMDIGS (x
);
1296 t2
= (SCM_BIGUP (t2
) + ds
[nd
]) % z
;
1299 return SCM_MAKINUM (sgn
? -t2
: t2
);
1302 #ifndef SCM_DIGSTOOBIG
1303 unsigned long t2
= scm_pseudolong (z
);
1304 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
1305 (SCM_BIGDIG
*) & t2
, SCM_DIGSPERLONG
,
1308 SCM_BIGDIG t2
[SCM_DIGSPERLONG
];
1309 scm_longdigs (z
, t2
);
1310 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
1311 t2
, SCM_DIGSPERLONG
,
1319 scm_divbigbig (SCM_BIGDIG
*x
, scm_sizet nx
, SCM_BIGDIG
*y
, scm_sizet ny
, int sgn
, int modes
)
1321 /* modes description
1325 3 quotient but returns 0 if division is not exact. */
1326 scm_sizet i
= 0, j
= 0;
1328 unsigned long t2
= 0;
1330 SCM_BIGDIG d
= 0, qhat
, *zds
, *yds
;
1331 /* algorithm requires nx >= ny */
1335 case 0: /* remainder -- just return x */
1336 z
= scm_mkbig (nx
, sgn
);
1337 zds
= SCM_BDIGITS (z
);
1344 case 1: /* scm_modulo -- return y-x */
1345 z
= scm_mkbig (ny
, sgn
);
1346 zds
= SCM_BDIGITS (z
);
1349 num
+= (long) y
[i
] - x
[i
];
1352 zds
[i
] = num
+ SCM_BIGRAD
;
1367 zds
[i
++] = num
+ SCM_BIGRAD
;
1378 return SCM_INUM0
; /* quotient is zero */
1380 return 0; /* the division is not exact */
1383 z
= scm_mkbig (nx
== ny
? nx
+ 2 : nx
+ 1, sgn
);
1384 zds
= SCM_BDIGITS (z
);
1388 ny
--; /* in case y came in as a psuedolong */
1389 if (y
[ny
- 1] < (SCM_BIGRAD
>> 1))
1390 { /* normalize operands */
1391 d
= SCM_BIGRAD
/ (y
[ny
- 1] + 1);
1392 newy
= scm_mkbig (ny
, 0);
1393 yds
= SCM_BDIGITS (newy
);
1396 t2
+= (unsigned long) y
[j
] * d
;
1397 yds
[j
++] = SCM_BIGLO (t2
);
1398 t2
= SCM_BIGDN (t2
);
1405 t2
+= (unsigned long) x
[j
] * d
;
1406 zds
[j
++] = SCM_BIGLO (t2
);
1407 t2
= SCM_BIGDN (t2
);
1417 j
= nx
== ny
? nx
+ 1 : nx
; /* dividend needs more digits than divisor */
1419 { /* loop over digits of quotient */
1420 if (zds
[j
] == y
[ny
- 1])
1421 qhat
= SCM_BIGRAD
- 1;
1423 qhat
= (SCM_BIGUP (zds
[j
]) + zds
[j
- 1]) / y
[ny
- 1];
1430 { /* multiply and subtract */
1431 t2
+= (unsigned long) y
[i
] * qhat
;
1432 num
+= zds
[j
- ny
+ i
] - SCM_BIGLO (t2
);
1435 zds
[j
- ny
+ i
] = num
+ SCM_BIGRAD
;
1440 zds
[j
- ny
+ i
] = num
;
1443 t2
= SCM_BIGDN (t2
);
1446 num
+= zds
[j
- ny
+ i
] - t2
; /* borrow from high digit; don't update */
1448 { /* "add back" required */
1454 num
+= (long) zds
[j
- ny
+ i
] + y
[i
];
1455 zds
[j
- ny
+ i
] = SCM_BIGLO (num
);
1456 num
= SCM_BIGDN (num
);
1467 case 3: /* check that remainder==0 */
1468 for (j
= ny
; j
&& !zds
[j
- 1]; --j
);
1471 case 2: /* move quotient down in z */
1472 j
= (nx
== ny
? nx
+ 2 : nx
+ 1) - ny
;
1473 for (i
= 0; i
< j
; i
++)
1474 zds
[i
] = zds
[i
+ ny
];
1477 case 1: /* subtract for scm_modulo */
1483 num
+= y
[i
] - zds
[i
];
1487 zds
[i
] = num
+ SCM_BIGRAD
;
1499 case 0: /* just normalize remainder */
1501 scm_divbigdig (zds
, ny
, d
);
1504 for (j
= ny
; j
&& !zds
[j
- 1]; --j
);
1505 if (j
* SCM_BITSPERDIG
<= sizeof (SCM
) * SCM_CHAR_BIT
)
1506 if (SCM_INUMP (z
= scm_big2inum (z
, j
)))
1508 return scm_adjbig (z
, j
);
1516 /*** NUMBERS -> STRINGS ***/
1519 static const double fx
[] =
1520 { 0.0, 5e-1, 5e-2, 5e-3, 5e-4, 5e-5,
1521 5e-6, 5e-7, 5e-8, 5e-9, 5e-10,
1522 5e-11, 5e-12, 5e-13, 5e-14, 5e-15,
1523 5e-16, 5e-17, 5e-18, 5e-19, 5e-20};
1529 idbl2str (double f
, char *a
)
1531 int efmt
, dpt
, d
, i
, wp
= scm_dblprec
;
1536 goto zero
; /*{a[0]='0'; a[1]='.'; a[2]='0'; return 3;} */
1555 #ifdef DBL_MIN_10_EXP /* Prevent unnormalized values, as from
1556 make-uniform-vector, from causing infinite loops. */
1560 if (exp
-- < DBL_MIN_10_EXP
)
1566 if (exp
++ > DBL_MAX_10_EXP
)
1581 if (f
+ fx
[wp
] >= 10.0)
1588 dpt
= (exp
+ 9999) % 3;
1592 efmt
= (exp
< -3) || (exp
> wp
+ 2);
1617 if (f
+ fx
[wp
] >= 1.0)
1631 if ((dpt
> 4) && (exp
> 6))
1633 d
= (a
[0] == '-' ? 2 : 1);
1634 for (i
= ch
++; i
> d
; i
--)
1647 if (a
[ch
- 1] == '.')
1648 a
[ch
++] = '0'; /* trailing zero */
1657 for (i
= 10; i
<= exp
; i
*= 10);
1658 for (i
/= 10; i
; i
/= 10)
1660 a
[ch
++] = exp
/ i
+ '0';
1669 iflo2str (SCM flt
, char *str
)
1673 if (SCM_SINGP (flt
))
1674 i
= idbl2str (SCM_FLO (flt
), str
);
1677 i
= idbl2str (SCM_REAL (flt
), str
);
1678 if (SCM_CPLXP (flt
))
1680 if (0 <= SCM_IMAG (flt
)) /* jeh */
1681 str
[i
++] = '+'; /* jeh */
1682 i
+= idbl2str (SCM_IMAG (flt
), &str
[i
]);
1687 #endif /* SCM_FLOATS */
1689 /* convert a long to a string (unterminated). returns the number of
1690 characters in the result.
1692 p is destination: worst case (base 2) is SCM_INTBUFLEN */
1694 scm_iint2str (long num
, int rad
, char *p
)
1698 unsigned long n
= (num
< 0) ? -num
: num
;
1700 for (n
/= rad
; n
> 0; n
/= rad
)
1717 p
[i
] = d
+ ((d
< 10) ? '0' : 'a' - 10);
1726 big2str (SCM b
, unsigned int radix
)
1728 SCM t
= scm_copybig (b
, 0); /* sign of temp doesn't matter */
1729 register SCM_BIGDIG
*ds
= SCM_BDIGITS (t
);
1730 scm_sizet i
= SCM_NUMDIGS (t
);
1731 scm_sizet j
= radix
== 16 ? (SCM_BITSPERDIG
* i
) / 4 + 2
1732 : radix
>= 10 ? (SCM_BITSPERDIG
* i
* 241L) / 800 + 2
1733 : (SCM_BITSPERDIG
* i
) + 2;
1735 scm_sizet radct
= 0;
1736 scm_sizet ch
; /* jeh */
1737 SCM_BIGDIG radpow
= 1, radmod
= 0;
1738 SCM ss
= scm_makstr ((long) j
, 0);
1739 char *s
= SCM_CHARS (ss
), c
;
1740 while ((long) radpow
* radix
< SCM_BIGRAD
)
1745 s
[0] = scm_tc16_bigneg
== SCM_TYP16 (b
) ? '-' : '+';
1746 while ((i
|| radmod
) && j
)
1750 radmod
= (SCM_BIGDIG
) scm_divbigdig (ds
, i
, radpow
);
1758 s
[--j
] = c
< 10 ? c
+ '0' : c
+ 'a' - 10;
1760 ch
= s
[0] == '-' ? 1 : 0; /* jeh */
1763 for (i
= j
; j
< SCM_LENGTH (ss
); j
++)
1764 s
[ch
+ j
- i
] = s
[j
]; /* jeh */
1765 scm_vector_set_length_x (ss
, /* jeh */
1766 (SCM
) SCM_MAKINUM (ch
+ SCM_LENGTH (ss
) - i
));
1769 return scm_return_first (ss
, t
);
1774 SCM_DEFINE (scm_number_to_string
, "number->string", 1, 1, 0,
1777 #define FUNC_NAME s_scm_number_to_string
1780 SCM_VALIDATE_INUM_MIN_DEF_COPY (2,radix
,2,10,base
);
1784 char num_buf
[SCM_FLOBUFLEN
];
1786 SCM_ASRTGO (SCM_NIMP (x
), badx
);
1788 return big2str (x
, (unsigned int) base
);
1789 #ifndef SCM_RECKLESS
1797 SCM_ASSERT (SCM_INEXP (x
),
1798 x
, SCM_ARG1
, s_number_to_string
);
1800 return scm_makfromstr (num_buf
, iflo2str (x
, num_buf
), 0);
1806 SCM_ASSERT (SCM_BIGP (x
),
1807 x
, SCM_ARG1
, s_number_to_string
);
1808 return big2str (x
, (unsigned int) base
);
1811 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_number_to_string
);
1815 char num_buf
[SCM_INTBUFLEN
];
1816 return scm_makfromstr (num_buf
,
1817 scm_iint2str (SCM_INUM (x
),
1826 /* These print routines are stubbed here so that scm_repl.c doesn't need
1827 SCM_FLOATS or SCM_BIGDIGs conditionals */
1830 scm_floprint (SCM sexp
, SCM port
, scm_print_state
*pstate
)
1833 char num_buf
[SCM_FLOBUFLEN
];
1834 scm_lfwrite (num_buf
, iflo2str (sexp
, num_buf
), port
);
1836 scm_ipruk ("float", sexp
, port
);
1844 scm_bigprint (SCM exp
, SCM port
, scm_print_state
*pstate
)
1847 exp
= big2str (exp
, (unsigned int) 10);
1848 scm_lfwrite (SCM_CHARS (exp
), (scm_sizet
) SCM_LENGTH (exp
), port
);
1850 scm_ipruk ("bignum", exp
, port
);
1854 /*** END nums->strs ***/
1856 /*** STRINGS -> NUMBERS ***/
1859 scm_small_istr2int (char *str
, long len
, long radix
)
1861 register long n
= 0, ln
;
1866 return SCM_BOOL_F
; /* zero scm_length */
1868 { /* leading sign */
1873 return SCM_BOOL_F
; /* bad if lone `+' or `-' */
1878 switch (c
= str
[i
++])
1900 return SCM_BOOL_F
; /* bad digit for radix */
1903 /* Negation is a workaround for HP700 cc bug */
1904 if (n
> ln
|| (-n
> -SCM_MOST_NEGATIVE_FIXNUM
))
1908 return SCM_BOOL_F
; /* not a digit */
1913 if ((n
= -n
) > SCM_MOST_POSITIVE_FIXNUM
)
1915 return SCM_MAKINUM (n
);
1916 ovfl
: /* overflow scheme integer */
1923 scm_istr2int (char *str
, long len
, long radix
)
1926 register scm_sizet k
, blen
= 1;
1930 register SCM_BIGDIG
*ds
;
1931 register unsigned long t2
;
1934 return SCM_BOOL_F
; /* zero scm_length */
1936 /* Short numbers we parse directly into an int, to avoid the overhead
1937 of creating a bignum. */
1939 return scm_small_istr2int (str
, len
, radix
);
1942 j
= 1 + (4 * len
* sizeof (char)) / (SCM_BITSPERDIG
);
1943 else if (10 <= radix
)
1944 j
= 1 + (84 * len
* sizeof (char)) / (SCM_BITSPERDIG
* 25);
1946 j
= 1 + (len
* sizeof (char)) / (SCM_BITSPERDIG
);
1948 { /* leading sign */
1951 if (++i
== (unsigned) len
)
1952 return SCM_BOOL_F
; /* bad if lone `+' or `-' */
1954 res
= scm_mkbig (j
, '-' == str
[0]);
1955 ds
= SCM_BDIGITS (res
);
1960 switch (c
= str
[i
++])
1982 return SCM_BOOL_F
; /* bad digit for radix */
1988 /* printf ("k = %d, blen = %d, t2 = %ld, ds[k] = %d\n", k, blen, t2, ds[k]); */
1989 t2
+= ds
[k
] * radix
;
1990 ds
[k
++] = SCM_BIGLO (t2
);
1991 t2
= SCM_BIGDN (t2
);
1994 scm_num_overflow ("bignum");
2002 return SCM_BOOL_F
; /* not a digit */
2005 while (i
< (unsigned) len
);
2006 if (blen
* SCM_BITSPERDIG
/ SCM_CHAR_BIT
<= sizeof (SCM
))
2007 if (SCM_INUMP (res
= scm_big2inum (res
, blen
)))
2011 return scm_adjbig (res
, blen
);
2017 scm_istr2flo (char *str
, long len
, long radix
)
2019 register int c
, i
= 0;
2021 double res
= 0.0, tmp
= 0.0;
2027 return SCM_BOOL_F
; /* zero scm_length */
2030 { /* leading sign */
2043 return SCM_BOOL_F
; /* bad if lone `+' or `-' */
2045 if (str
[i
] == 'i' || str
[i
] == 'I')
2046 { /* handle `+i' and `-i' */
2047 if (lead_sgn
== 0.0)
2048 return SCM_BOOL_F
; /* must have leading sign */
2050 return SCM_BOOL_F
; /* `i' not last character */
2051 return scm_makdbl (0.0, lead_sgn
);
2054 { /* check initial digits */
2064 goto out1
; /* must be exponent */
2081 return SCM_BOOL_F
; /* bad digit for radix */
2082 res
= res
* radix
+ c
;
2083 flg
= 1; /* res is valid */
2092 /* if true, then we did see a digit above, and res is valid */
2096 /* By here, must have seen a digit,
2097 or must have next char be a `.' with radix==10 */
2099 if (!(str
[i
] == '.' && radix
== 10))
2102 while (str
[i
] == '#')
2103 { /* optional sharps */
2136 tmp
= tmp
* radix
+ c
;
2144 return SCM_BOOL_F
; /* `slash zero' not allowed */
2146 while (str
[i
] == '#')
2147 { /* optional sharps */
2157 { /* decimal point notation */
2159 return SCM_BOOL_F
; /* must be radix 10 */
2166 res
= res
* 10.0 + c
- '0';
2175 return SCM_BOOL_F
; /* no digits before or after decimal point */
2178 while (str
[i
] == '#')
2179 { /* ignore remaining sharps */
2198 int expsgn
= 1, expon
= 0;
2200 return SCM_BOOL_F
; /* only in radix 10 */
2202 return SCM_BOOL_F
; /* bad exponent */
2209 return SCM_BOOL_F
; /* bad exponent */
2211 if (str
[i
] < '0' || str
[i
] > '9')
2212 return SCM_BOOL_F
; /* bad exponent */
2218 expon
= expon
* 10 + c
- '0';
2220 return SCM_BOOL_F
; /* exponent too large */
2228 point
+= expsgn
* expon
;
2246 /* at this point, we have a legitimate floating point result */
2247 if (lead_sgn
== -1.0)
2250 return scm_makdbl (res
, 0.0);
2252 if (str
[i
] == 'i' || str
[i
] == 'I')
2253 { /* pure imaginary number */
2254 if (lead_sgn
== 0.0)
2255 return SCM_BOOL_F
; /* must have leading sign */
2257 return SCM_BOOL_F
; /* `i' not last character */
2258 return scm_makdbl (0.0, res
);
2270 { /* polar input for complex number */
2271 /* get a `real' for scm_angle */
2272 second
= scm_istr2flo (&str
[i
], (long) (len
- i
), radix
);
2273 if (!SCM_INEXP (second
))
2274 return SCM_BOOL_F
; /* not `real' */
2275 if (SCM_CPLXP (second
))
2276 return SCM_BOOL_F
; /* not `real' */
2277 tmp
= SCM_REALPART (second
);
2278 return scm_makdbl (res
* cos (tmp
), res
* sin (tmp
));
2284 /* at this point, last char must be `i' */
2285 if (str
[len
- 1] != 'i' && str
[len
- 1] != 'I')
2287 /* handles `x+i' and `x-i' */
2289 return scm_makdbl (res
, lead_sgn
);
2290 /* get a `ureal' for complex part */
2291 second
= scm_istr2flo (&str
[i
], (long) ((len
- i
) - 1), radix
);
2292 if (!SCM_INEXP (second
))
2293 return SCM_BOOL_F
; /* not `ureal' */
2294 if (SCM_CPLXP (second
))
2295 return SCM_BOOL_F
; /* not `ureal' */
2296 tmp
= SCM_REALPART (second
);
2298 return SCM_BOOL_F
; /* not `ureal' */
2299 return scm_makdbl (res
, (lead_sgn
* tmp
));
2301 #endif /* SCM_FLOATS */
2306 scm_istring2number (char *str
, long len
, long radix
)
2310 char ex_p
= 0, rx_p
= 0; /* Only allow 1 exactness and 1 radix prefix */
2313 if (*str
== '+' || *str
== '-') /* Catches lone `+' and `-' for speed */
2316 while ((len
- i
) >= 2 && str
[i
] == '#' && ++i
)
2362 return scm_istr2int (&str
[i
], len
- i
, radix
);
2364 res
= scm_istr2int (&str
[i
], len
- i
, radix
);
2365 if (SCM_NFALSEP (res
))
2369 return scm_istr2flo (&str
[i
], len
- i
, radix
);
2376 SCM_DEFINE (scm_string_to_number
, "string->number", 1, 1, 0,
2377 (SCM str
, SCM radix
),
2379 #define FUNC_NAME s_scm_string_to_number
2383 SCM_VALIDATE_ROSTRING (1,str
);
2384 SCM_VALIDATE_INUM_MIN_DEF_COPY (2,radix
,2,10,base
);
2385 answer
= scm_istring2number (SCM_ROCHARS (str
),
2388 return scm_return_first (answer
, str
);
2391 /*** END strs->nums ***/
2396 scm_makdbl (double x
, double y
)
2399 if ((y
== 0.0) && (x
== 0.0))
2406 #ifndef SCM_SINGLESONLY
2407 if ((-FLTMAX
< x
) && (x
< FLTMAX
) && (fx
== x
))
2410 SCM_NEWSMOB(z
,scm_tc_flo
,NULL
);
2415 #endif /* def SCM_SINGLES */
2416 SCM_NEWSMOB(z
,scm_tc_dblr
,scm_must_malloc (1L * sizeof (double), "real"));
2420 SCM_NEWSMOB(z
,scm_tc_dblc
,scm_must_malloc (2L * sizeof (double), "comkplex"));
2432 scm_bigequal (SCM x
, SCM y
)
2435 if (0 == scm_bigcomp (x
, y
))
2444 scm_floequal (SCM x
, SCM y
)
2447 if (SCM_REALPART (x
) != SCM_REALPART (y
))
2449 if (!(SCM_CPLXP (x
) && (SCM_IMAG (x
) != SCM_IMAG (y
))))
2458 SCM_REGISTER_PROC (s_number_p
, "number?", 1, 0, 0, scm_number_p
);
2460 SCM_DEFINE (scm_number_p
, "complex?", 1, 0, 0,
2463 #define FUNC_NAME s_scm_number_p
2483 SCM_REGISTER_PROC (s_real_p
, "real?", 1, 0, 0, scm_real_p
);
2486 SCM_DEFINE (scm_real_p
, "rational?", 1, 0, 0,
2489 #define FUNC_NAME s_scm_real_p
2507 SCM_DEFINE (scm_integer_p
, "integer?", 1, 0, 0,
2510 #define FUNC_NAME s_scm_integer_p
2525 r
= SCM_REALPART (x
);
2534 #endif /* SCM_FLOATS */
2536 SCM_DEFINE (scm_inexact_p
, "inexact?", 1, 0, 0,
2539 #define FUNC_NAME s_scm_inexact_p
2552 SCM_GPROC1 (s_eq_p
, "=", scm_tc7_rpsubr
, scm_num_eq_p
, g_eq_p
);
2555 scm_num_eq_p (SCM x
, SCM y
)
2565 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2571 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2573 return SCM_BOOL(0 == scm_bigcomp (x
, y
));
2574 SCM_ASRTGO (SCM_INEXP (y
), bady
);
2576 return ((SCM_REALP (y
) && (scm_big2dbl (x
) == SCM_REALPART (y
)))
2580 SCM_ASRTGO (SCM_INEXP (x
), badx
);
2582 SCM_GASSERT2 (SCM_INEXP (x
),
2583 g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2593 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2601 SCM_ASRTGO (SCM_INEXP (y
), bady
);
2603 SCM_ASRTGO (SCM_INEXP (y
), bady
);
2605 if (SCM_REALPART (x
) != SCM_REALPART (y
))
2608 return ((SCM_CPLXP (y
) && (SCM_IMAG (x
) == SCM_IMAG (y
)))
2611 return SCM_NEGATE_BOOL(SCM_CPLXP (y
));
2616 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2622 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2628 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2632 return ((SCM_REALP (y
) && (((double) SCM_INUM (x
)) == SCM_REALPART (y
)))
2640 SCM_GASSERT2 (SCM_BIGP (x
),
2641 g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2644 SCM_ASRTGO (SCM_BIGP (y
), bady
);
2645 return SCM_BOOL(0 == scm_bigcomp (x
, y
));
2652 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2657 SCM_GASSERT2 (SCM_INUMP (x
), g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2658 SCM_GASSERT2 (SCM_INUMP (y
), g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2661 return SCM_BOOL((long) x
== (long) y
);
2666 SCM_GPROC1 (s_less_p
, "<", scm_tc7_rpsubr
, scm_less_p
, g_less_p
);
2669 scm_less_p (SCM x
, SCM y
)
2678 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2683 return SCM_BOOL(SCM_BIGSIGN (x
));
2684 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2686 return SCM_BOOL(1 == scm_bigcomp (x
, y
));
2687 SCM_ASRTGO (SCM_REALP (y
), bady
);
2688 return ((scm_big2dbl (x
) < SCM_REALPART (y
))
2692 SCM_ASRTGO (SCM_REALP (x
), badx
);
2694 SCM_GASSERT2 (SCM_REALP (x
),
2695 g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2698 return ((SCM_REALPART (x
) < ((double) SCM_INUM (y
)))
2702 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2704 return SCM_BOOL(SCM_REALPART (x
) < scm_big2dbl (y
));
2705 SCM_ASRTGO (SCM_REALP (y
), bady
);
2707 SCM_ASRTGO (SCM_REALP (y
), bady
);
2709 return SCM_BOOL(SCM_REALPART (x
) < SCM_REALPART (y
));
2714 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2716 return SCM_NEGATE_BOOL(SCM_BIGSIGN (y
));
2720 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2726 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2729 return ((((double) SCM_INUM (x
)) < SCM_REALPART (y
))
2737 SCM_GASSERT2 (SCM_BIGP (x
),
2738 g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2740 return SCM_BOOL(SCM_BIGSIGN (x
));
2741 SCM_ASRTGO (SCM_BIGP (y
), bady
);
2742 return SCM_BOOL(1 == scm_bigcomp (x
, y
));
2749 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2751 return SCM_NEGATE_BOOL(SCM_BIGSIGN (y
));
2754 SCM_GASSERT2 (SCM_INUMP (x
), g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2755 SCM_GASSERT2 (SCM_INUMP (y
), g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2758 return SCM_BOOL((long) x
< (long) y
);
2762 SCM_DEFINE1 (scm_gr_p
, ">", scm_tc7_rpsubr
,
2765 #define FUNC_NAME s_scm_gr_p
2767 return scm_less_p (y
, x
);
2773 SCM_DEFINE1 (scm_leq_p
, "<=", scm_tc7_rpsubr
,
2776 #define FUNC_NAME s_scm_leq_p
2778 return SCM_BOOL_NOT (scm_less_p (y
, x
));
2784 SCM_DEFINE1 (scm_geq_p
, ">=", scm_tc7_rpsubr
,
2787 #define FUNC_NAME s_scm_geq_p
2789 return SCM_BOOL_NOT (scm_less_p (x
, y
));
2795 SCM_GPROC (s_zero_p
, "zero?", 1, 0, 0, scm_zero_p
, g_zero_p
);
2804 SCM_ASRTGO (SCM_NIMP (z
), badz
);
2810 SCM_WTA_DISPATCH_1 (g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2813 SCM_GASSERT1 (SCM_INEXP (z
),
2814 g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2816 return SCM_BOOL(z
== scm_flo0
);
2822 SCM_GASSERT1 (SCM_BIGP (z
),
2823 g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2827 SCM_GASSERT1 (SCM_INUMP (z
), g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2830 return SCM_BOOL(z
== SCM_INUM0
);
2835 SCM_GPROC (s_positive_p
, "positive?", 1, 0, 0, scm_positive_p
, g_positive_p
);
2838 scm_positive_p (SCM x
)
2844 SCM_ASRTGO (SCM_NIMP (x
), badx
);
2846 return SCM_BOOL(SCM_TYP16 (x
) == scm_tc16_bigpos
);
2850 SCM_WTA_DISPATCH_1 (g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2853 SCM_GASSERT1 (SCM_REALP (x
),
2854 g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2856 return SCM_BOOL(SCM_REALPART (x
) > 0.0);
2862 SCM_GASSERT1 (SCM_BIGP (x
),
2863 g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2864 return SCM_BOOL(SCM_TYP16 (x
) == scm_tc16_bigpos
);
2867 SCM_GASSERT1 (SCM_INUMP (x
), g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2870 return SCM_BOOL(SCM_INUM(x
) > 0);
2875 SCM_GPROC (s_negative_p
, "negative?", 1, 0, 0, scm_negative_p
, g_negative_p
);
2878 scm_negative_p (SCM x
)
2884 SCM_ASRTGO (SCM_NIMP (x
), badx
);
2886 return SCM_NEGATE_BOOL(SCM_TYP16 (x
) == scm_tc16_bigpos
);
2887 if (!(SCM_REALP (x
)))
2890 SCM_WTA_DISPATCH_1 (g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2893 SCM_GASSERT1 (SCM_REALP (x
),
2894 g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2896 return SCM_BOOL(SCM_REALPART (x
) < 0.0);
2902 SCM_GASSERT1 (SCM_BIGP (x
),
2903 g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2904 return SCM_BOOL(SCM_TYP16 (x
) == scm_tc16_bigneg
);
2907 SCM_GASSERT1 (SCM_INUMP (x
), g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2910 return SCM_BOOL(SCM_INUM(x
) < 0);
2914 SCM_GPROC1 (s_max
, "max", scm_tc7_asubr
, scm_max
, g_max
);
2917 scm_max (SCM x
, SCM y
)
2924 SCM_GASSERT0 (!SCM_UNBNDP (x
),
2925 g_max
, scm_makfrom0str (s_max
), SCM_WNA
, 0);
2926 SCM_GASSERT1 (SCM_NUMBERP (x
), g_max
, x
, SCM_ARG1
, s_max
);
2936 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARG1
, s_max
);
2941 return SCM_BIGSIGN (x
) ? y
: x
;
2942 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2944 return (1 == scm_bigcomp (x
, y
)) ? y
: x
;
2945 SCM_ASRTGO (SCM_REALP (y
), bady
);
2946 z
= scm_big2dbl (x
);
2947 return (z
< SCM_REALPART (y
)) ? y
: scm_makdbl (z
, 0.0);
2949 SCM_ASRTGO (SCM_REALP (x
), badx2
);
2951 SCM_GASSERT2 (SCM_REALP (x
),
2952 g_max
, x
, y
, SCM_ARG1
, s_max
);
2955 return ((SCM_REALPART (x
) < (z
= SCM_INUM (y
)))
2956 ? scm_makdbl (z
, 0.0)
2959 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2961 return ((SCM_REALPART (x
) < (z
= scm_big2dbl (y
)))
2962 ? scm_makdbl (z
, 0.0)
2964 SCM_ASRTGO (SCM_REALP (y
), bady
);
2966 SCM_ASRTGO (SCM_REALP (y
), bady
);
2968 return (SCM_REALPART (x
) < SCM_REALPART (y
)) ? y
: x
;
2973 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2975 return SCM_BIGSIGN (y
) ? x
: y
;
2976 if (!(SCM_REALP (y
)))
2979 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARGn
, s_max
);
2985 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARGn
, s_max
);
2988 return (((z
= SCM_INUM (x
)) < SCM_REALPART (y
))
2990 : scm_makdbl (z
, 0.0));
2996 SCM_GASSERT2 (SCM_BIGP (x
),
2997 g_max
, x
, y
, SCM_ARG1
, s_max
);
2999 return SCM_BIGSIGN (x
) ? y
: x
;
3000 SCM_ASRTGO (SCM_BIGP (y
), bady
);
3001 return (1 == scm_bigcomp (x
, y
)) ? y
: x
;
3008 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARGn
, s_max
);
3010 return SCM_BIGSIGN (y
) ? x
: y
;
3013 SCM_GASSERT2 (SCM_INUMP (x
), g_max
, x
, y
, SCM_ARG1
, s_max
);
3014 SCM_GASSERT2 (SCM_INUMP (y
), g_max
, x
, y
, SCM_ARGn
, s_max
);
3017 return ((long) x
< (long) y
) ? y
: x
;
3021 #define SCM_SWAP(x,y) do { SCM t = x; x = y; y = t; } while (0)
3025 SCM_GPROC1 (s_min
, "min", scm_tc7_asubr
, scm_min
, g_min
);
3028 scm_min (SCM x
, SCM y
)
3035 SCM_GASSERT0 (!SCM_UNBNDP (x
),
3036 g_min
, scm_makfrom0str (s_min
), SCM_WNA
, 0);
3037 SCM_GASSERT1 (SCM_NUMBERP (x
), g_min
, x
, SCM_ARG1
, s_min
);
3047 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARG1
, s_min
);
3052 return SCM_BIGSIGN (x
) ? x
: y
;
3053 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3055 return (-1 == scm_bigcomp (x
, y
)) ? y
: x
;
3056 SCM_ASRTGO (SCM_REALP (y
), bady
);
3057 z
= scm_big2dbl (x
);
3058 return (z
> SCM_REALPART (y
)) ? y
: scm_makdbl (z
, 0.0);
3060 SCM_ASRTGO (SCM_REALP (x
), badx2
);
3062 SCM_GASSERT2 (SCM_REALP (x
),
3063 g_min
, x
, y
, SCM_ARG1
, s_min
);
3066 return ((SCM_REALPART (x
) > (z
= SCM_INUM (y
)))
3067 ? scm_makdbl (z
, 0.0)
3070 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3072 return ((SCM_REALPART (x
) > (z
= scm_big2dbl (y
)))
3073 ? scm_makdbl (z
, 0.0)
3075 SCM_ASRTGO (SCM_REALP (y
), bady
);
3077 SCM_ASRTGO (SCM_REALP (y
), bady
);
3079 return (SCM_REALPART (x
) > SCM_REALPART (y
)) ? y
: x
;
3084 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3086 return SCM_BIGSIGN (y
) ? y
: x
;
3087 if (!(SCM_REALP (y
)))
3090 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARGn
, s_min
);
3096 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARGn
, s_min
);
3099 return (((z
= SCM_INUM (x
)) > SCM_REALPART (y
))
3101 : scm_makdbl (z
, 0.0));
3107 SCM_GASSERT2 (SCM_BIGP (x
),
3108 g_min
, x
, y
, SCM_ARG1
, s_min
);
3110 return SCM_BIGSIGN (x
) ? x
: y
;
3111 SCM_ASRTGO (SCM_BIGP (y
), bady
);
3112 return (-1 == scm_bigcomp (x
, y
)) ? y
: x
;
3119 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARGn
, s_min
);
3121 return SCM_BIGSIGN (y
) ? y
: x
;
3124 SCM_GASSERT2 (SCM_INUMP (x
), g_min
, x
, y
, SCM_ARG1
, s_min
);
3125 SCM_GASSERT2 (SCM_INUMP (y
), g_min
, x
, y
, SCM_ARGn
, s_min
);
3128 return ((long) x
> (long) y
) ? y
: x
;
3134 SCM_GPROC1 (s_sum
, "+", scm_tc7_asubr
, scm_sum
, g_sum
);
3137 This is sick, sick, sick code.
3141 scm_sum (SCM x
, SCM y
)
3147 SCM_GASSERT1 (SCM_NUMBERP (x
), g_sum
, x
, SCM_ARG1
, s_sum
);
3157 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARG1
, s_sum
);
3166 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3169 if (SCM_NUMDIGS (x
) > SCM_NUMDIGS (y
))
3173 return scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3177 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3179 return scm_makdbl (scm_big2dbl (x
) + SCM_REALPART (y
),
3180 SCM_CPLXP (y
) ? SCM_IMAG (y
) : 0.0);
3182 # endif /* SCM_BIGDIG */
3183 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3191 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3197 else if (!SCM_INEXP (y
))
3200 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3202 # else /* SCM_BIGDIG */
3206 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3208 # endif /* SCM_BIGDIG */
3215 return scm_makdbl (SCM_REALPART (x
) + SCM_REALPART (y
), i
);
3221 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3226 # ifndef SCM_DIGSTOOBIG
3227 long z
= scm_pseudolong (SCM_INUM (x
));
3228 return scm_addbig ((SCM_BIGDIG
*) & z
,
3230 (x
< 0) ? 0x0100 : 0,
3232 # else /* SCM_DIGSTOOBIG */
3233 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3234 scm_longdigs (SCM_INUM (x
), zdigs
);
3235 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3237 # endif /* SCM_DIGSTOOBIG */
3240 # endif /* SCM_BIGDIG */
3241 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3243 return scm_makdbl (SCM_INUM (x
) + SCM_REALPART (y
),
3244 SCM_CPLXP (y
) ? SCM_IMAG (y
) : 0.0);
3246 #else /* SCM_FLOATS */
3251 SCM_ASRTGO (SCM_BIGP (x
), badx2
);
3257 SCM_ASRTGO (SCM_BIGP (y
), bady
);
3258 if (SCM_NUMDIGS (x
) > SCM_NUMDIGS (y
))
3260 return scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
), SCM_BIGSIGN (x
),
3268 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3272 # ifndef SCM_DIGSTOOBIG
3273 long z
= scm_pseudolong (SCM_INUM (x
));
3274 return scm_addbig (&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
3276 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3277 scm_longdigs (SCM_INUM (x
), zdigs
);
3278 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
3279 # endif /* SCM_DIGSTOOBIG */
3282 # else /* SCM_BIGDIG */
3283 SCM_ASRTGO (SCM_INUMP (x
), badx2
);
3284 SCM_GASSERT2 (SCM_INUMP (y
), g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3285 # endif/* SCM_BIGDIG */
3286 #endif /* SCM_FLOATS */
3289 long int i
= SCM_INUM (x
) + SCM_INUM (y
);
3290 if (SCM_FIXABLE (i
))
3291 return SCM_MAKINUM (i
);
3293 return scm_long2big (i
);
3294 #else /* SCM_BIGDIG */
3297 return scm_makdbl ((double) i
, 0.0);
3299 scm_num_overflow (s_sum
);
3300 return SCM_UNSPECIFIED
;
3301 # endif/* SCM_FLOATS */
3302 #endif /* SCM_BIGDIG */
3309 SCM_GPROC1 (s_difference
, "-", scm_tc7_asubr
, scm_difference
, g_difference
);
3312 HWN:FIXME:: This is sick,sick, sick code. Rewrite me.
3315 scm_difference (SCM x
, SCM y
)
3325 SCM_GASSERT0 (!SCM_UNBNDP (x
), g_difference
,
3326 scm_makfrom0str (s_difference
), SCM_WNA
, 0);
3328 SCM_WTA_DISPATCH_1 (g_difference
, x
, SCM_ARG1
, s_difference
);
3333 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARG1
, s_difference
);
3341 x
= scm_copybig (x
, !SCM_BIGSIGN (x
));
3342 return (SCM_NUMDIGS (x
) * SCM_BITSPERDIG
/ SCM_CHAR_BIT
3344 ? scm_big2inum (x
, SCM_NUMDIGS (x
))
3348 SCM_ASRTGO (SCM_INEXP (x
), badx
);
3349 return scm_makdbl (- SCM_REALPART (x
),
3350 SCM_CPLXP (x
) ? -SCM_IMAG (x
) : 0.0);
3353 return scm_sum (x
, SCM_MAKINUM (- SCM_INUM (y
)));
3355 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3359 return ((SCM_NUMDIGS (x
) < SCM_NUMDIGS (y
))
3360 ? scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3363 : scm_addbig (SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3364 SCM_BIGSIGN (y
) ^ 0x0100,
3366 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3367 return scm_makdbl (scm_big2dbl (x
) - SCM_REALPART (y
),
3368 SCM_CPLXP (y
) ? -SCM_IMAG (y
) : 0.0);
3370 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3372 return scm_makdbl (SCM_REALPART (x
) - scm_big2dbl (y
),
3373 SCM_CPLXP (x
) ? SCM_IMAG (x
) : 0.0);
3374 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3376 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3377 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3382 return scm_makdbl (SCM_REAL (x
) - SCM_REAL (y
),
3383 SCM_IMAG (x
) - SCM_IMAG (y
));
3385 return scm_makdbl (SCM_REAL (x
) - SCM_REALPART (y
), SCM_IMAG (x
));
3387 return scm_makdbl (SCM_REALPART (x
) - SCM_REALPART (y
),
3388 SCM_CPLXP (y
) ? - SCM_IMAG (y
) : 0.0);
3398 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3401 #ifndef SCM_DIGSTOOBIG
3402 long z
= scm_pseudolong (SCM_INUM (x
));
3403 return scm_addbig ((SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3404 (x
< 0) ? 0x0100 : 0,
3407 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3408 scm_longdigs (SCM_INUM (x
), zdigs
);
3409 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3416 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3422 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3425 return scm_makdbl (SCM_INUM (x
) - SCM_REALPART (y
),
3426 SCM_CPLXP (y
) ? -SCM_IMAG (y
) : 0.0);
3432 SCM_GASSERT2 (SCM_BIGP (x
),
3433 g_difference
, x
, y
, SCM_ARG1
, s_difference
);
3436 x
= scm_copybig (x
, !SCM_BIGSIGN (x
));
3437 return (SCM_NUMDIGS (x
) * SCM_BITSPERDIG
/ SCM_CHAR_BIT
3439 ? scm_big2inum (x
, SCM_NUMDIGS (x
))
3444 #ifndef SCM_DIGSTOOBIG
3445 long z
= scm_pseudolong (SCM_INUM (y
));
3446 return scm_addbig (&z
, SCM_DIGSPERLONG
, (y
< 0) ? 0 : 0x0100, x
, 0);
3448 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3449 scm_longdigs (SCM_INUM (x
), zdigs
);
3450 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (y
< 0) ? 0 : 0x0100,
3454 SCM_ASRTGO (SCM_BIGP (y
), bady
);
3455 return (SCM_NUMDIGS (x
) < SCM_NUMDIGS (y
)) ?
3456 scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
), SCM_BIGSIGN (x
),
3458 scm_addbig (SCM_BDIGITS (y
), SCM_NUMDIGS (y
), SCM_BIGSIGN (y
) ^ 0x0100,
3471 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3474 #ifndef SCM_DIGSTOOBIG
3475 long z
= scm_pseudolong (SCM_INUM (x
));
3476 return scm_addbig (&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3479 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3480 scm_longdigs (SCM_INUM (x
), zdigs
);
3481 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3487 SCM_GASSERT2 (SCM_INUMP (x
), g_difference
, x
, y
, SCM_ARG1
, s_difference
);
3493 SCM_GASSERT2 (SCM_INUMP (y
), g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3496 cx
= SCM_INUM (x
) - SCM_INUM (y
);
3498 if (SCM_FIXABLE (cx
))
3499 return SCM_MAKINUM (cx
);
3501 return scm_long2big (cx
);
3504 return scm_makdbl ((double) cx
, 0.0);
3506 scm_num_overflow (s_difference
);
3507 return SCM_UNSPECIFIED
;
3515 SCM_GPROC1 (s_product
, "*", scm_tc7_asubr
, scm_product
, g_product
);
3518 scm_product (SCM x
, SCM y
)
3523 return SCM_MAKINUM (1L);
3524 SCM_GASSERT1 (SCM_NUMBERP (x
), g_product
, x
, SCM_ARG1
, s_product
);
3535 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARG1
, s_product
);
3546 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3548 return scm_mulbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3549 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3550 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
));
3551 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3554 double bg
= scm_big2dbl (x
);
3555 return scm_makdbl (bg
* SCM_REALPART (y
),
3556 SCM_CPLXP (y
) ? bg
* SCM_IMAG (y
) : 0.0);
3559 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3561 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3571 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3579 else if (!(SCM_INEXP (y
)))
3582 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARGn
, s_product
);
3588 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARGn
, s_product
);
3594 return scm_makdbl (SCM_REAL (x
) * SCM_REAL (y
)
3595 - SCM_IMAG (x
) * SCM_IMAG (y
),
3596 SCM_REAL (x
) * SCM_IMAG (y
)
3597 + SCM_IMAG (x
) * SCM_REAL (y
));
3599 return scm_makdbl (SCM_REAL (x
) * SCM_REALPART (y
),
3600 SCM_IMAG (x
) * SCM_REALPART (y
));
3602 return scm_makdbl (SCM_REALPART (x
) * SCM_REALPART (y
),
3604 ? SCM_REALPART (x
) * SCM_IMAG (y
)
3610 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3616 if (SCM_MAKINUM (1L) == x
)
3619 #ifndef SCM_DIGSTOOBIG
3620 long z
= scm_pseudolong (SCM_INUM (x
));
3621 return scm_mulbig ((SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3622 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3623 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3625 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3626 scm_longdigs (SCM_INUM (x
), zdigs
);
3627 return scm_mulbig (zdigs
, SCM_DIGSPERLONG
,
3628 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3629 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3633 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3635 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3638 return scm_makdbl (SCM_INUM (x
) * SCM_REALPART (y
),
3639 SCM_CPLXP (y
) ? SCM_INUM (x
) * SCM_IMAG (y
) : 0.0);
3645 SCM_ASRTGO (SCM_BIGP (x
), badx2
);
3653 SCM_ASRTGO (SCM_BIGP (y
), bady
);
3654 return scm_mulbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3655 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3656 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
));
3663 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARGn
, s_product
);
3668 if (SCM_MAKINUM (1L) == x
)
3671 #ifndef SCM_DIGSTOOBIG
3672 long z
= scm_pseudolong (SCM_INUM (x
));
3673 return scm_mulbig (&z
, SCM_DIGSPERLONG
,
3674 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3675 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3677 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3678 scm_longdigs (SCM_INUM (x
), zdigs
);
3679 return scm_mulbig (zdigs
, SCM_DIGSPERLONG
,
3680 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3681 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3686 SCM_ASRTGO (SCM_INUMP (x
), badx2
);
3687 SCM_GASSERT (SCM_INUMP (y
), g_product
, x
, y
, SCM_ARGn
, s_product
);
3697 y
= SCM_MAKINUM (k
);
3698 if (k
!= SCM_INUM (y
) || k
/ i
!= j
)
3701 int sgn
= (i
< 0) ^ (j
< 0);
3702 #ifndef SCM_DIGSTOOBIG
3703 i
= scm_pseudolong (i
);
3704 j
= scm_pseudolong (j
);
3705 return scm_mulbig ((SCM_BIGDIG
*) & i
, SCM_DIGSPERLONG
,
3706 (SCM_BIGDIG
*) & j
, SCM_DIGSPERLONG
, sgn
);
3707 #else /* SCM_DIGSTOOBIG */
3708 SCM_BIGDIG idigs
[SCM_DIGSPERLONG
];
3709 SCM_BIGDIG jdigs
[SCM_DIGSPERLONG
];
3710 scm_longdigs (i
, idigs
);
3711 scm_longdigs (j
, jdigs
);
3712 return scm_mulbig (idigs
, SCM_DIGSPERLONG
,
3713 jdigs
, SCM_DIGSPERLONG
,
3719 return scm_makdbl (((double) i
) * ((double) j
), 0.0);
3721 scm_num_overflow (s_product
);
3731 scm_num2dbl (SCM a
, const char *why
)
3734 return (double) SCM_INUM (a
);
3736 SCM_ASSERT (SCM_NIMP (a
), a
, "wrong type argument", why
);
3738 return (SCM_REALPART (a
));
3741 return scm_big2dbl (a
);
3743 SCM_ASSERT (0, a
, "wrong type argument", why
);
3745 unreachable, hopefully.
3747 return (double) 0.0; /* ugh. */
3748 /* return SCM_UNSPECIFIED; */
3752 SCM_GPROC1 (s_divide
, "/", scm_tc7_asubr
, scm_divide
, g_divide
);
3755 scm_divide (SCM x
, SCM y
)
3761 if (!(SCM_NIMP (x
)))
3765 SCM_GASSERT0 (!SCM_UNBNDP (x
),
3766 g_divide
, scm_makfrom0str (s_divide
), SCM_WNA
, 0);
3768 SCM_WTA_DISPATCH_1 (g_divide
, x
, SCM_ARG1
, s_divide
);
3773 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARG1
, s_divide
);
3780 return scm_makdbl (1.0 / scm_big2dbl (x
), 0.0);
3782 SCM_ASRTGO (SCM_INEXP (x
), badx
);
3784 return scm_makdbl (1.0 / SCM_REALPART (x
), 0.0);
3788 return scm_makdbl (r
/ d
, -i
/ d
);
3795 long int z
= SCM_INUM (y
);
3796 #ifndef SCM_RECKLESS
3798 scm_num_overflow (s_divide
);
3806 SCM w
= scm_copybig (x
, SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0));
3807 return (scm_divbigdig (SCM_BDIGITS (w
), SCM_NUMDIGS (w
),
3809 ? scm_makdbl (scm_big2dbl (x
) / SCM_INUM (y
), 0.0)
3812 #ifndef SCM_DIGSTOOBIG
3813 /*ugh! Does anyone know what this is supposed to do?*/
3814 z
= scm_pseudolong (z
);
3815 z
= SCM_INUM(scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3816 (SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3817 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3));
3820 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3821 scm_longdigs (z
, zdigs
);
3822 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3823 zdigs
, SCM_DIGSPERLONG
,
3824 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
3827 return z
? SCM_ASSCM (z
) : scm_makdbl (scm_big2dbl (x
) / SCM_INUM (y
), 0.0);
3829 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3832 SCM z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3833 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3834 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
), 3);
3835 return z
? z
: scm_makdbl (scm_big2dbl (x
) / scm_big2dbl (y
),
3838 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3840 return scm_makdbl (scm_big2dbl (x
) / SCM_REALPART (y
), 0.0);
3841 a
= scm_big2dbl (x
);
3845 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3852 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3855 d
= scm_big2dbl (y
);
3858 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3860 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3864 d
= SCM_REALPART (y
);
3866 return scm_makdbl (SCM_REALPART (x
) / d
,
3867 SCM_CPLXP (x
) ? SCM_IMAG (x
) / d
: 0.0);
3869 a
= SCM_REALPART (x
);
3875 return scm_makdbl ((a
* r
+ SCM_IMAG (x
) * i
) / d
,
3876 (SCM_IMAG (x
) * r
- a
* i
) / d
);
3880 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
3882 return scm_makdbl (1.0 / ((double) SCM_INUM (x
)), 0.0);
3887 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3889 return scm_makdbl (SCM_INUM (x
) / scm_big2dbl (y
), 0.0);
3890 if (!(SCM_INEXP (y
)))
3893 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARGn
, s_divide
);
3899 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARGn
, s_divide
);
3903 return scm_makdbl (SCM_INUM (x
) / SCM_REALPART (y
), 0.0);
3909 return scm_makdbl ((a
* r
) / d
, (-a
* i
) / d
);
3916 SCM_GASSERT2 (SCM_BIGP (x
),
3917 g_divide
, x
, y
, SCM_ARG1
, s_divide
);
3931 SCM w
= scm_copybig (x
, SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0));
3932 if (scm_divbigdig (SCM_BDIGITS (w
), SCM_NUMDIGS (w
),
3937 #ifndef SCM_DIGSTOOBIG
3938 z
= scm_pseudolong (z
);
3939 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3940 &z
, SCM_DIGSPERLONG
,
3941 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
3944 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3945 scm_longdigs (z
, zdigs
);
3946 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3947 zdigs
, SCM_DIGSPERLONG
,
3948 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
3954 SCM_ASRTGO (SCM_BIGP (y
), bady
);
3955 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3956 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3957 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
), 3);
3965 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
3974 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARGn
, s_divide
);
3979 SCM_GASSERT2 (SCM_INUMP (x
), g_divide
, x
, y
, SCM_ARG1
, s_divide
);
3982 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
3986 SCM_GASSERT2 (SCM_INUMP (y
), g_divide
, x
, y
, SCM_ARGn
, s_divide
);
3990 long z
= SCM_INUM (y
);
3991 if ((0 == z
) || SCM_INUM (x
) % z
)
3993 z
= SCM_INUM (x
) / z
;
3994 if (SCM_FIXABLE (z
))
3995 return SCM_MAKINUM (z
);
3997 return scm_long2big (z
);
4001 return scm_makdbl (((double) SCM_INUM (x
)) / ((double) SCM_INUM (y
)), 0.0);
4004 scm_num_overflow (s_divide
);
4005 return SCM_UNSPECIFIED
;
4014 SCM_GPROC1 (s_asinh
, "$asinh", scm_tc7_cxr
, (SCM (*)()) scm_asinh
, g_asinh
);
4017 scm_asinh (double x
)
4019 return log (x
+ sqrt (x
* x
+ 1));
4025 SCM_GPROC1 (s_acosh
, "$acosh", scm_tc7_cxr
, (SCM (*)()) scm_acosh
, g_acosh
);
4028 scm_acosh (double x
)
4030 return log (x
+ sqrt (x
* x
- 1));
4036 SCM_GPROC1 (s_atanh
, "$atanh", scm_tc7_cxr
, (SCM (*)()) scm_atanh
, g_atanh
);
4039 scm_atanh (double x
)
4041 return 0.5 * log ((1 + x
) / (1 - x
));
4047 SCM_GPROC1 (s_truncate
, "truncate", scm_tc7_cxr
, (SCM (*)()) scm_truncate
, g_truncate
);
4050 scm_truncate (double x
)
4059 SCM_GPROC1 (s_round
, "round", scm_tc7_cxr
, (SCM (*)()) scm_round
, g_round
);
4062 scm_round (double x
)
4064 double plus_half
= x
+ 0.5;
4065 double result
= floor (plus_half
);
4066 /* Adjust so that the scm_round is towards even. */
4067 return (plus_half
== result
&& plus_half
/ 2 != floor (plus_half
/ 2))
4068 ? result
- 1 : result
;
4073 SCM_GPROC1 (s_exact_to_inexact
, "exact->inexact", scm_tc7_cxr
, (SCM (*)()) scm_exact_to_inexact
, g_exact_to_inexact
);
4076 scm_exact_to_inexact (double z
)
4082 SCM_GPROC1 (s_i_floor
, "floor", scm_tc7_cxr
, (SCM (*)()) floor
, g_i_floor
);
4083 SCM_GPROC1 (s_i_ceil
, "ceiling", scm_tc7_cxr
, (SCM (*)()) ceil
, g_i_ceil
);
4084 SCM_GPROC1 (s_i_sqrt
, "$sqrt", scm_tc7_cxr
, (SCM (*)()) sqrt
, g_i_sqrt
);
4085 SCM_GPROC1 (s_i_abs
, "$abs", scm_tc7_cxr
, (SCM (*)()) fabs
, g_i_abs
);
4086 SCM_GPROC1 (s_i_exp
, "$exp", scm_tc7_cxr
, (SCM (*)()) exp
, g_i_exp
);
4087 SCM_GPROC1 (s_i_log
, "$log", scm_tc7_cxr
, (SCM (*)()) log
, g_i_log
);
4088 SCM_GPROC1 (s_i_sin
, "$sin", scm_tc7_cxr
, (SCM (*)()) sin
, g_i_sin
);
4089 SCM_GPROC1 (s_i_cos
, "$cos", scm_tc7_cxr
, (SCM (*)()) cos
, g_i_cos
);
4090 SCM_GPROC1 (s_i_tan
, "$tan", scm_tc7_cxr
, (SCM (*)()) tan
, g_i_tan
);
4091 SCM_GPROC1 (s_i_asin
, "$asin", scm_tc7_cxr
, (SCM (*)()) asin
, g_i_asin
);
4092 SCM_GPROC1 (s_i_acos
, "$acos", scm_tc7_cxr
, (SCM (*)()) acos
, g_i_acos
);
4093 SCM_GPROC1 (s_i_atan
, "$atan", scm_tc7_cxr
, (SCM (*)()) atan
, g_i_atan
);
4094 SCM_GPROC1 (s_i_sinh
, "$sinh", scm_tc7_cxr
, (SCM (*)()) sinh
, g_i_sinh
);
4095 SCM_GPROC1 (s_i_cosh
, "$cosh", scm_tc7_cxr
, (SCM (*)()) cosh
, g_i_cosh
);
4096 SCM_GPROC1 (s_i_tanh
, "$tanh", scm_tc7_cxr
, (SCM (*)()) tanh
, g_i_tanh
);
4103 static void scm_two_doubles (SCM z1
,
4105 const char *sstring
,
4109 scm_two_doubles (SCM z1
, SCM z2
, const char *sstring
, struct dpair
*xy
)
4112 xy
->x
= SCM_INUM (z1
);
4116 SCM_ASRTGO (SCM_NIMP (z1
), badz1
);
4118 xy
->x
= scm_big2dbl (z1
);
4121 #ifndef SCM_RECKLESS
4122 if (!SCM_REALP (z1
))
4123 badz1
:scm_wta (z1
, (char *) SCM_ARG1
, sstring
);
4125 xy
->x
= SCM_REALPART (z1
);
4129 SCM_ASSERT (SCM_REALP (z1
), z1
, SCM_ARG1
, sstring
);
4130 xy
->x
= SCM_REALPART (z1
);
4135 xy
->y
= SCM_INUM (z2
);
4139 SCM_ASRTGO (SCM_NIMP (z2
), badz2
);
4141 xy
->y
= scm_big2dbl (z2
);
4144 #ifndef SCM_RECKLESS
4145 if (!(SCM_REALP (z2
)))
4146 badz2
:scm_wta (z2
, (char *) SCM_ARG2
, sstring
);
4148 xy
->y
= SCM_REALPART (z2
);
4152 SCM_ASSERT (SCM_REALP (z2
), z2
, SCM_ARG2
, sstring
);
4153 xy
->y
= SCM_REALPART (z2
);
4162 SCM_DEFINE (scm_sys_expt
, "$expt", 2, 0, 0,
4165 #define FUNC_NAME s_scm_sys_expt
4168 scm_two_doubles (z1
, z2
, FUNC_NAME
, &xy
);
4169 return scm_makdbl (pow (xy
.x
, xy
.y
), 0.0);
4175 SCM_DEFINE (scm_sys_atan2
, "$atan2", 2, 0, 0,
4178 #define FUNC_NAME s_scm_sys_atan2
4181 scm_two_doubles (z1
, z2
, FUNC_NAME
, &xy
);
4182 return scm_makdbl (atan2 (xy
.x
, xy
.y
), 0.0);
4188 SCM_DEFINE (scm_make_rectangular
, "make-rectangular", 2, 0, 0,
4191 #define FUNC_NAME s_scm_make_rectangular
4194 scm_two_doubles (z1
, z2
, FUNC_NAME
, &xy
);
4195 return scm_makdbl (xy
.x
, xy
.y
);
4201 SCM_DEFINE (scm_make_polar
, "make-polar", 2, 0, 0,
4204 #define FUNC_NAME s_scm_make_polar
4207 scm_two_doubles (z1
, z2
, FUNC_NAME
, &xy
);
4208 return scm_makdbl (xy
.x
* cos (xy
.y
), xy
.x
* sin (xy
.y
));
4215 SCM_GPROC (s_real_part
, "real-part", 1, 0, 0, scm_real_part
, g_real_part
);
4218 scm_real_part (SCM z
)
4223 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4226 if (!(SCM_INEXP (z
)))
4229 SCM_WTA_DISPATCH_1 (g_real_part
, z
, SCM_ARG1
, s_real_part
);
4232 SCM_GASSERT1 (SCM_INEXP (z
),
4233 g_real_part
, z
, SCM_ARG1
, s_real_part
);
4236 return scm_makdbl (SCM_REAL (z
), 0.0);
4243 SCM_GPROC (s_imag_part
, "imag-part", 1, 0, 0, scm_imag_part
, g_imag_part
);
4246 scm_imag_part (SCM z
)
4251 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4254 if (!(SCM_INEXP (z
)))
4257 SCM_WTA_DISPATCH_1 (g_imag_part
, z
, SCM_ARG1
, s_imag_part
);
4260 SCM_GASSERT1 (SCM_INEXP (z
),
4261 g_imag_part
, z
, SCM_ARG1
, s_imag_part
);
4264 return scm_makdbl (SCM_IMAG (z
), 0.0);
4270 SCM_GPROC (s_magnitude
, "magnitude", 1, 0, 0, scm_magnitude
, g_magnitude
);
4273 scm_magnitude (SCM z
)
4278 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4281 if (!(SCM_INEXP (z
)))
4284 SCM_WTA_DISPATCH_1 (g_magnitude
, z
, SCM_ARG1
, s_magnitude
);
4287 SCM_GASSERT1 (SCM_INEXP (z
),
4288 g_magnitude
, z
, SCM_ARG1
, s_magnitude
);
4292 double i
= SCM_IMAG (z
), r
= SCM_REAL (z
);
4293 return scm_makdbl (sqrt (i
* i
+ r
* r
), 0.0);
4295 return scm_makdbl (fabs (SCM_REALPART (z
)), 0.0);
4301 SCM_GPROC (s_angle
, "angle", 1, 0, 0, scm_angle
, g_angle
);
4309 x
= (z
>= SCM_INUM0
) ? 1.0 : -1.0;
4313 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4316 x
= (SCM_TYP16 (z
) == scm_tc16_bigpos
) ? 1.0 : -1.0;
4319 if (!(SCM_INEXP (z
)))
4322 SCM_WTA_DISPATCH_1 (g_angle
, z
, SCM_ARG1
, s_angle
);
4325 SCM_GASSERT1 (SCM_INEXP (z
), g_angle
, z
, SCM_ARG1
, s_angle
);
4329 x
= SCM_REALPART (z
);
4335 return scm_makdbl (atan2 (y
, x
), 0.0);
4339 SCM_DEFINE (scm_inexact_to_exact
, "inexact->exact", 1, 0, 0,
4342 #define FUNC_NAME s_scm_inexact_to_exact
4347 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4350 #ifndef SCM_RECKLESS
4351 if (!(SCM_REALP (z
)))
4358 SCM_VALIDATE_REAL (1,z
);
4362 double u
= floor (SCM_REALPART (z
) + 0.5);
4363 if ((u
<= SCM_MOST_POSITIVE_FIXNUM
) && (-u
<= -SCM_MOST_NEGATIVE_FIXNUM
))
4365 /* Negation is a workaround for HP700 cc bug */
4366 SCM ans
= SCM_MAKINUM ((long) u
);
4367 if (SCM_INUM (ans
) == (long) u
)
4370 SCM_ASRTGO (isfinite (u
), badz
); /* problem? */
4371 return scm_dbl2big (u
);
4374 return SCM_MAKINUM ((long) floor (SCM_REALPART (z
) + 0.5));
4381 #else /* ~SCM_FLOATS */
4382 SCM_GPROC (s_trunc
, "truncate", 1, 0, 0, scm_trunc
, g_trunc
);
4387 SCM_GASSERT2 (SCM_INUMP (x
), g_trunc
, x
, y
, SCM_ARG1
, s_truncate
);
4393 #endif /* SCM_FLOATS */
4397 /* d must be integer */
4400 scm_dbl2big (double d
)
4406 double u
= (d
< 0) ? -d
: d
;
4407 while (0 != floor (u
))
4412 ans
= scm_mkbig (i
, d
< 0);
4413 digits
= SCM_BDIGITS (ans
);
4421 #ifndef SCM_RECKLESS
4423 scm_num_overflow ("dbl2big");
4434 scm_sizet i
= SCM_NUMDIGS (b
);
4435 SCM_BIGDIG
*digits
= SCM_BDIGITS (b
);
4437 ans
= digits
[i
] + SCM_BIGRAD
* ans
;
4438 if (scm_tc16_bigneg
== SCM_TYP16 (b
))
4447 scm_long2num (long sl
)
4449 if (!SCM_FIXABLE (sl
))
4452 return scm_long2big (sl
);
4455 return scm_makdbl ((double) sl
, 0.0);
4461 return SCM_MAKINUM (sl
);
4465 #ifdef HAVE_LONG_LONGS
4468 scm_long_long2num (long_long sl
)
4470 if (!SCM_FIXABLE (sl
))
4473 return scm_long_long2big (sl
);
4476 return scm_makdbl ((double) sl
, 0.0);
4482 return SCM_MAKINUM (sl
);
4489 scm_ulong2num (unsigned long sl
)
4491 if (!SCM_POSFIXABLE (sl
))
4494 return scm_ulong2big (sl
);
4497 return scm_makdbl ((double) sl
, 0.0);
4503 return SCM_MAKINUM (sl
);
4508 scm_num2long (SCM num
, char *pos
, const char *s_caller
)
4512 if (SCM_INUMP (num
))
4514 res
= SCM_INUM (num
);
4517 SCM_ASRTGO (SCM_NIMP (num
), wrong_type_arg
);
4519 if (SCM_REALP (num
))
4521 volatile double u
= SCM_REALPART (num
);
4532 unsigned long oldres
= 0;
4534 /* can't use res directly in case num is -2^31. */
4535 unsigned long pos_res
= 0;
4537 for (l
= SCM_NUMDIGS (num
); l
--;)
4539 pos_res
= SCM_BIGUP (pos_res
) + SCM_BDIGITS (num
)[l
];
4540 /* check for overflow. */
4541 if (pos_res
< oldres
)
4545 if (SCM_TYP16 (num
) == scm_tc16_bigpos
)
4561 scm_wrong_type_arg (s_caller
, (int) pos
, num
);
4563 scm_out_of_range (s_caller
, num
);
4568 #ifdef HAVE_LONG_LONGS
4571 scm_num2long_long (SCM num
, char *pos
, const char *s_caller
)
4575 if (SCM_INUMP (num
))
4577 res
= SCM_INUM (num
);
4580 SCM_ASRTGO (SCM_NIMP (num
), wrong_type_arg
);
4582 if (SCM_REALP (num
))
4584 double u
= SCM_REALPART (num
);
4587 if ((res
< 0 && u
> 0) || (res
> 0 && u
< 0)) /* check for overflow. */
4596 unsigned long long oldres
= 0;
4598 /* can't use res directly in case num is -2^63. */
4599 unsigned long long pos_res
= 0;
4601 for (l
= SCM_NUMDIGS (num
); l
--;)
4603 pos_res
= SCM_LONGLONGBIGUP (pos_res
) + SCM_BDIGITS (num
)[l
];
4604 /* check for overflow. */
4605 if (pos_res
< oldres
)
4609 if (SCM_TYP16 (num
) == scm_tc16_bigpos
)
4625 scm_wrong_type_arg (s_caller
, (int) pos
, num
);
4627 scm_out_of_range (s_caller
, num
);
4634 scm_num2ulong (SCM num
, char *pos
, const char *s_caller
)
4638 if (SCM_INUMP (num
))
4640 if (SCM_INUM (num
) < 0)
4642 res
= SCM_INUM (num
);
4645 SCM_ASRTGO (SCM_NIMP (num
), wrong_type_arg
);
4647 if (SCM_REALP (num
))
4649 double u
= SCM_REALPART (num
);
4660 unsigned long oldres
= 0;
4664 for (l
= SCM_NUMDIGS (num
); l
--;)
4666 res
= SCM_BIGUP (res
) + SCM_BDIGITS (num
)[l
];
4675 scm_wrong_type_arg (s_caller
, (int) pos
, num
);
4677 scm_out_of_range (s_caller
, num
);
4684 add1 (double f
, double *fsum
)
4696 scm_add_feature("complex");
4698 scm_add_feature("inexact");
4700 SCM_NEWSMOB(scm_flo0
,scm_tc_flo
,NULL
);
4702 SCM_NEWSMOB(scm_flo0
,scm_tc_dblr
,scm_must_malloc (1L * sizeof (double), "real"));
4703 SCM_REAL (scm_flo0
) = 0.0;
4706 scm_dblprec
= (DBL_DIG
> 20) ? 20 : DBL_DIG
;
4708 { /* determine floating point precision */
4710 double fsum
= 1.0 + f
;
4714 if (++scm_dblprec
> 20)
4718 scm_dblprec
= scm_dblprec
- 1;
4720 #endif /* DBL_DIG */
4722 #include "numbers.x"