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 GUILE_PROC1 (scm_logand
, "logand", scm_tc7_asubr
,
515 "Returns the integer which is the bit-wise AND of the two integer
520 (number->string (logand #b1100 #b1010) 2)
522 #define FUNC_NAME s_scm_logand
528 return SCM_MAKINUM (-1);
531 SCM_VALIDATE_INUM_COPY(1,n1
,i1
);
532 SCM_VALIDATE_INUM_COPY(2,n2
,i2
);
533 return scm_ulong2num (i1
& i2
);
537 GUILE_PROC1 (scm_logior
, "logior", scm_tc7_asubr
,
539 "Returns the integer which is the bit-wise OR of the two integer
544 (number->string (logior #b1100 #b1010) 2)
547 #define FUNC_NAME s_scm_logior
556 SCM_VALIDATE_INUM_COPY(1,n1
,i1
);
557 SCM_VALIDATE_INUM_COPY(2,n2
,i2
);
558 return scm_ulong2num (i1
| i2
);
562 GUILE_PROC1 (scm_logxor
, "logxor", scm_tc7_asubr
,
564 "Returns the integer which is the bit-wise XOR of the two integer
569 (number->string (logxor #b1100 #b1010) 2)
572 #define FUNC_NAME s_scm_logxor
581 SCM_VALIDATE_INUM_COPY(1,n1
,i1
);
582 SCM_VALIDATE_INUM_COPY(2,n2
,i2
);
583 return scm_ulong2num (i1
^ i2
);
587 SCM_DEFINE (scm_logtest
, "logtest", 2, 0, 0,
590 #define FUNC_NAME s_scm_logtest
593 SCM_VALIDATE_INUM_COPY(1,n1
,i1
);
594 SCM_VALIDATE_INUM_COPY(2,n2
,i2
);
595 return SCM_BOOL(i1
& i2
);
600 SCM_DEFINE (scm_logbit_p
, "logbit?", 2, 0, 0,
603 #define FUNC_NAME s_scm_logbit_p
606 SCM_VALIDATE_INUM_COPY(1,n1
,i1
);
607 SCM_VALIDATE_INUM_COPY(2,n2
,i2
);
608 return SCM_BOOL((1 << i1
) & i2
);
614 GUILE_PROC1 (scm_logand
, "logand", scm_tc7_asubr
,
617 #define FUNC_NAME s_scm_logand
623 return SCM_MAKINUM (-1);
626 SCM_VALIDATE_INUM_COPY(1,n1
,i1
);
627 SCM_VALIDATE_INUM_COPY(2,n2
,i2
);
628 return SCM_MAKINUM (i1
& i2
);
632 GUILE_PROC1 (scm_logior
, "logior", scm_tc7_asubr
,
635 #define FUNC_NAME s_scm_logior
644 SCM_VALIDATE_INUM_COPY(1,n1
,i1
);
645 SCM_VALIDATE_INUM_COPY(2,n2
,i2
);
646 return SCM_MAKINUM (i1
| i2
);
650 GUILE_PROC1 (scm_logxor
, "logxor", scm_tc7_asubr
,
653 #define FUNC_NAME s_scm_logxor
662 SCM_VALIDATE_INUM_COPY(1,n1
,i1
);
663 SCM_VALIDATE_INUM_COPY(2,n2
,i2
);
664 return SCM_MAKINUM (i1
^ i2
);
668 SCM_DEFINE (scm_logtest
, "logtest", 2, 0, 0,
671 (logtest j k) @equiv{} (not (zero? (logand j k)))
673 (logtest #b0100 #b1011) @result{} #f
674 (logtest #b0100 #b0111) @result{} #t
676 #define FUNC_NAME s_scm_logtest
679 SCM_VALIDATE_INUM_COPY(1,n1
,i1
);
680 SCM_VALIDATE_INUM_COPY(2,n2
,i2
);
681 return SCM_BOOL(i1
& i2
);
685 SCM_DEFINE (scm_logbit_p
, "logbit?", 2, 0, 0,
688 (logbit? index j) @equiv{} (logtest (integer-expt 2 index) j)
690 (logbit? 0 #b1101) @result{} #t
691 (logbit? 1 #b1101) @result{} #f
692 (logbit? 2 #b1101) @result{} #t
693 (logbit? 3 #b1101) @result{} #t
694 (logbit? 4 #b1101) @result{} #f
696 #define FUNC_NAME s_scm_logbit_p
699 SCM_VALIDATE_INUM_MIN_COPY(1,n1
,0,i1
);
700 SCM_VALIDATE_INUM_COPY(2,n2
,i2
);
701 return SCM_BOOL((1 << i1
) & i2
);
706 SCM_DEFINE (scm_lognot
, "lognot", 1, 0, 0,
708 "Returns the integer which is the 2s-complement of the integer argument.
712 (number->string (lognot #b10000000) 2)
713 @result{} \"-10000001\"
714 (number->string (lognot #b0) 2)
718 #define FUNC_NAME s_scm_lognot
720 SCM_VALIDATE_INUM(1,n
);
721 return scm_difference (SCM_MAKINUM (-1L), n
);
725 SCM_DEFINE (scm_integer_expt
, "integer-expt", 2, 0, 0,
727 "Returns @var{n} raised to the non-negative integer exponent @var{k}.
736 #define FUNC_NAME s_scm_integer_expt
738 SCM acc
= SCM_MAKINUM (1L);
741 if (SCM_INUM0
== z1
|| acc
== z1
)
743 else if (SCM_MAKINUM (-1L) == z1
)
744 return SCM_BOOL_F
== scm_even_p (z2
) ? z1
: acc
;
746 SCM_VALIDATE_INUM_COPY(2,z2
,i2
);
750 z1
= scm_divide (z1
, SCM_UNDEFINED
);
757 return scm_product (acc
, z1
);
759 acc
= scm_product (acc
, z1
);
760 z1
= scm_product (z1
, z1
);
766 SCM_DEFINE (scm_ash
, "ash", 2, 0, 0,
768 "Returns an integer equivalent to
769 @code{(inexact->exact (floor (* @var{int} (expt 2 @var{count}))))}.@refill
773 (number->string (ash #b1 3) 2)
775 (number->string (ash #b1010 -1) 2)
778 #define FUNC_NAME s_scm_ash
780 /* GJB:FIXME:: what is going on here? */
781 SCM res
= SCM_INUM (n
);
782 SCM_VALIDATE_INUM(2,cnt
);
786 res
= scm_integer_expt (SCM_MAKINUM (2), SCM_MAKINUM (-SCM_INUM (cnt
)));
787 if (SCM_NFALSEP (scm_negative_p (n
)))
788 return scm_sum (SCM_MAKINUM (-1L),
789 scm_quotient (scm_sum (SCM_MAKINUM (1L), n
), res
));
791 return scm_quotient (n
, res
);
794 return scm_product (n
, scm_integer_expt (SCM_MAKINUM (2), cnt
));
796 SCM_VALIDATE_INUM(1,n
)
797 cnt
= SCM_INUM (cnt
);
799 return SCM_MAKINUM (SCM_SRS (res
, -cnt
));
800 res
= SCM_MAKINUM (res
<< cnt
);
801 if (SCM_INUM (res
) >> cnt
!= SCM_INUM (n
))
802 scm_num_overflow (FUNC_NAME
);
808 /* GJB:FIXME: do not use SCMs as integers! */
809 SCM_DEFINE (scm_bit_extract
, "bit-extract", 3, 0, 0,
810 (SCM n
, SCM start
, SCM end
),
811 "Returns the integer composed of the @var{start} (inclusive) through
812 @var{end} (exclusive) bits of @var{n}. The @var{start}th bit becomes
813 the 0-th bit in the result.@refill
817 (number->string (bit-extract #b1101101010 0 4) 2)
819 (number->string (bit-extract #b1101101010 4 9) 2)
822 #define FUNC_NAME s_scm_bit_extract
824 SCM_VALIDATE_INUM(1,n
);
825 SCM_VALIDATE_INUM_MIN(2,start
,0);
826 SCM_VALIDATE_INUM_MIN(3,end
,0);
827 start
= SCM_INUM (start
);
828 end
= SCM_INUM (end
);
829 SCM_ASSERT (end
>= start
, SCM_MAKINUM (end
), SCM_OUTOFRANGE
, FUNC_NAME
);
833 scm_logand (scm_difference (scm_integer_expt (SCM_MAKINUM (2),
834 SCM_MAKINUM (end
- start
)),
836 scm_ash (n
, SCM_MAKINUM (-start
)));
838 SCM_VALIDATE_INUM(1,n
);
840 return SCM_MAKINUM ((SCM_INUM (n
) >> start
) & ((1L << (end
- start
)) - 1));
844 static const char scm_logtab
[] = {
845 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
848 SCM_DEFINE (scm_logcount
, "logcount", 1, 0, 0,
850 "Returns the number of bits in integer @var{n}. If integer is positive,
851 the 1-bits in its binary representation are counted. If negative, the
852 0-bits in its two's-complement binary representation are counted. If 0,
857 (logcount #b10101010)
864 #define FUNC_NAME s_scm_logcount
866 register unsigned long c
= 0;
873 SCM_VALIDATE_BIGINT(1,n
);
875 return scm_logcount (scm_difference (SCM_MAKINUM (-1L), n
));
876 ds
= SCM_BDIGITS (n
);
877 for (i
= SCM_NUMDIGS (n
); i
--;)
878 for (d
= ds
[i
]; d
; d
>>= 4)
879 c
+= scm_logtab
[15 & d
];
880 return SCM_MAKINUM (c
);
883 SCM_VALIDATE_INUM(1,n
);
885 if ((nn
= SCM_INUM (n
)) < 0)
888 c
+= scm_logtab
[15 & nn
];
889 return SCM_MAKINUM (c
);
894 static const char scm_ilentab
[] = {
895 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
898 SCM_DEFINE (scm_integer_length
, "integer-length", 1, 0, 0,
900 "Returns the number of bits neccessary to represent @var{n}.
904 (integer-length #b10101010)
908 (integer-length #b1111)
911 #define FUNC_NAME s_scm_integer_length
913 register unsigned long c
= 0;
920 SCM_VALIDATE_BIGINT(1,n
);
922 return scm_integer_length (scm_difference (SCM_MAKINUM (-1L), n
));
923 ds
= SCM_BDIGITS (n
);
924 d
= ds
[c
= SCM_NUMDIGS (n
) - 1];
925 for (c
*= SCM_BITSPERDIG
; d
; d
>>= 4)
928 l
= scm_ilentab
[15 & d
];
930 return SCM_MAKINUM (c
- 4 + l
);
933 SCM_VALIDATE_INUM(1,n
);
935 if ((nn
= SCM_INUM (n
)) < 0)
940 l
= scm_ilentab
[15 & nn
];
942 return SCM_MAKINUM (c
- 4 + l
);
948 static const char s_bignum
[] = "bignum";
951 scm_mkbig (scm_sizet nlen
, int sign
)
954 /* Cast to SCM to avoid signed/unsigned comparison warnings. */
955 if (((v
<< 16) >> 16) != (SCM
) nlen
)
956 scm_wta (SCM_MAKINUM (nlen
), (char *) SCM_NALLOC
, s_bignum
);
959 SCM_SETCHARS (v
, scm_must_malloc ((long) (nlen
* sizeof (SCM_BIGDIG
)),
961 SCM_SETNUMDIGS (v
, nlen
, sign
? scm_tc16_bigneg
: scm_tc16_bigpos
);
968 scm_big2inum (SCM b
, scm_sizet l
)
970 unsigned long num
= 0;
971 SCM_BIGDIG
*tmp
= SCM_BDIGITS (b
);
973 num
= SCM_BIGUP (num
) + tmp
[l
];
974 if (SCM_TYP16 (b
) == scm_tc16_bigpos
)
976 if (SCM_POSFIXABLE (num
))
977 return SCM_MAKINUM (num
);
979 else if (SCM_UNEGFIXABLE (num
))
980 return SCM_MAKINUM (-num
);
985 static const char s_adjbig
[] = "scm_adjbig";
988 scm_adjbig (SCM b
, scm_sizet nlen
)
990 scm_sizet nsiz
= nlen
;
991 if (((nsiz
<< 16) >> 16) != nlen
)
992 scm_wta (scm_ulong2num (nsiz
), (char *) SCM_NALLOC
, s_adjbig
);
998 scm_must_realloc ((char *) SCM_CHARS (b
),
999 (long) (SCM_NUMDIGS (b
) * sizeof (SCM_BIGDIG
)),
1000 (long) (nsiz
* sizeof (SCM_BIGDIG
)), s_adjbig
));
1002 SCM_SETCHARS (b
, digits
);
1003 SCM_SETNUMDIGS (b
, nsiz
, SCM_TYP16 (b
));
1015 scm_sizet nlen
= SCM_NUMDIGS (b
);
1017 int nlen
= SCM_NUMDIGS (b
); /* unsigned nlen breaks on Cray when nlen => 0 */
1019 SCM_BIGDIG
*zds
= SCM_BDIGITS (b
);
1020 while (nlen
-- && !zds
[nlen
]);
1022 if (nlen
* SCM_BITSPERDIG
/ SCM_CHAR_BIT
<= sizeof (SCM
))
1023 if (SCM_INUMP (b
= scm_big2inum (b
, (scm_sizet
) nlen
)))
1025 if (SCM_NUMDIGS (b
) == nlen
)
1027 return scm_adjbig (b
, (scm_sizet
) nlen
);
1033 scm_copybig (SCM b
, int sign
)
1035 scm_sizet i
= SCM_NUMDIGS (b
);
1036 SCM ans
= scm_mkbig (i
, sign
);
1037 SCM_BIGDIG
*src
= SCM_BDIGITS (b
), *dst
= SCM_BDIGITS (ans
);
1046 scm_long2big (long n
)
1050 SCM ans
= scm_mkbig (SCM_DIGSPERLONG
, n
< 0);
1051 digits
= SCM_BDIGITS (ans
);
1054 while (i
< SCM_DIGSPERLONG
)
1056 digits
[i
++] = SCM_BIGLO (n
);
1057 n
= SCM_BIGDN ((unsigned long) n
);
1062 #ifdef HAVE_LONG_LONGS
1065 scm_long_long2big (long_long n
)
1075 if ((long long) tn
== n
)
1076 return scm_long2big (tn
);
1082 for (tn
= n
, n_digits
= 0;
1084 ++n_digits
, tn
= SCM_BIGDN ((ulong_long
) tn
))
1089 ans
= scm_mkbig (n_digits
, n
< 0);
1090 digits
= SCM_BDIGITS (ans
);
1093 while (i
< n_digits
)
1095 digits
[i
++] = SCM_BIGLO (n
);
1096 n
= SCM_BIGDN ((ulong_long
) n
);
1104 scm_2ulong2big (unsigned long *np
)
1111 ans
= scm_mkbig (2 * SCM_DIGSPERLONG
, 0);
1112 digits
= SCM_BDIGITS (ans
);
1115 for (i
= 0; i
< SCM_DIGSPERLONG
; ++i
)
1117 digits
[i
] = SCM_BIGLO (n
);
1118 n
= SCM_BIGDN ((unsigned long) n
);
1121 for (i
= 0; i
< SCM_DIGSPERLONG
; ++i
)
1123 digits
[i
+ SCM_DIGSPERLONG
] = SCM_BIGLO (n
);
1124 n
= SCM_BIGDN ((unsigned long) n
);
1132 scm_ulong2big (unsigned long n
)
1136 SCM ans
= scm_mkbig (SCM_DIGSPERLONG
, 0);
1137 digits
= SCM_BDIGITS (ans
);
1138 while (i
< SCM_DIGSPERLONG
)
1140 digits
[i
++] = SCM_BIGLO (n
);
1149 scm_bigcomp (SCM x
, SCM y
)
1151 int xsign
= SCM_BIGSIGN (x
);
1152 int ysign
= SCM_BIGSIGN (y
);
1153 scm_sizet xlen
, ylen
;
1155 /* Look at the signs, first. */
1161 /* They're the same sign, so see which one has more digits. Note
1162 that, if they are negative, the longer number is the lesser. */
1163 ylen
= SCM_NUMDIGS (y
);
1164 xlen
= SCM_NUMDIGS (x
);
1166 return (xsign
) ? -1 : 1;
1168 return (xsign
) ? 1 : -1;
1170 /* They have the same number of digits, so find the most significant
1171 digit where they differ. */
1175 if (SCM_BDIGITS (y
)[xlen
] != SCM_BDIGITS (x
)[xlen
])
1176 /* Make the discrimination based on the digit that differs. */
1177 return ((SCM_BDIGITS (y
)[xlen
] > SCM_BDIGITS (x
)[xlen
])
1179 : (xsign
? 1 : -1));
1182 /* The numbers are identical. */
1186 #ifndef SCM_DIGSTOOBIG
1190 scm_pseudolong (long x
)
1195 SCM_BIGDIG bd
[SCM_DIGSPERLONG
];
1201 while (i
< SCM_DIGSPERLONG
)
1203 p
.bd
[i
++] = SCM_BIGLO (x
);
1206 /* p.bd[0] = SCM_BIGLO(x); p.bd[1] = SCM_BIGDN(x); */
1214 scm_longdigs (long x
, SCM_BIGDIG digs
[])
1219 while (i
< SCM_DIGSPERLONG
)
1221 digs
[i
++] = SCM_BIGLO (x
);
1230 scm_addbig (SCM_BIGDIG
*x
, scm_sizet nx
, int xsgn
, SCM bigy
, int sgny
)
1232 /* Assumes nx <= SCM_NUMDIGS(bigy) */
1233 /* Assumes xsgn and sgny scm_equal either 0 or 0x0100 */
1235 scm_sizet i
= 0, ny
= SCM_NUMDIGS (bigy
);
1236 SCM z
= scm_copybig (bigy
, SCM_BIGSIGN (bigy
) ^ sgny
);
1237 SCM_BIGDIG
*zds
= SCM_BDIGITS (z
);
1238 if (xsgn
^ SCM_BIGSIGN (z
))
1242 num
+= (long) zds
[i
] - x
[i
];
1245 zds
[i
] = num
+ SCM_BIGRAD
;
1250 zds
[i
] = SCM_BIGLO (num
);
1255 if (num
&& nx
== ny
)
1259 SCM_SETCAR (z
, SCM_CAR (z
) ^ 0x0100);
1262 num
+= (SCM_BIGRAD
- 1) - zds
[i
];
1263 zds
[i
++] = SCM_BIGLO (num
);
1264 num
= SCM_BIGDN (num
);
1274 zds
[i
++] = num
+ SCM_BIGRAD
;
1279 zds
[i
++] = SCM_BIGLO (num
);
1288 num
+= (long) zds
[i
] + x
[i
];
1289 zds
[i
++] = SCM_BIGLO (num
);
1290 num
= SCM_BIGDN (num
);
1298 zds
[i
++] = SCM_BIGLO (num
);
1299 num
= SCM_BIGDN (num
);
1305 z
= scm_adjbig (z
, ny
+ 1);
1306 SCM_BDIGITS (z
)[ny
] = num
;
1310 return scm_normbig (z
);
1315 scm_mulbig (SCM_BIGDIG
*x
, scm_sizet nx
, SCM_BIGDIG
*y
, scm_sizet ny
, int sgn
)
1317 scm_sizet i
= 0, j
= nx
+ ny
;
1318 unsigned long n
= 0;
1319 SCM z
= scm_mkbig (j
, sgn
);
1320 SCM_BIGDIG
*zds
= SCM_BDIGITS (z
);
1330 n
+= zds
[i
+ j
] + ((unsigned long) x
[i
] * y
[j
]);
1331 zds
[i
+ j
++] = SCM_BIGLO (n
);
1343 return scm_normbig (z
);
1347 /* Sun's compiler complains about the fact that this function has an
1348 ANSI prototype in numbers.h, but a K&R declaration here, and the
1349 two specify different promotions for the third argument. I'm going
1350 to turn this into an ANSI declaration, and see if anyone complains
1351 about it not being K&R. */
1354 scm_divbigdig (SCM_BIGDIG
* ds
,
1358 register unsigned long t2
= 0;
1361 t2
= SCM_BIGUP (t2
) + ds
[h
];
1371 scm_divbigint (SCM x
, long z
, int sgn
, int mode
)
1377 register unsigned long t2
= 0;
1378 register SCM_BIGDIG
*ds
= SCM_BDIGITS (x
);
1379 scm_sizet nd
= SCM_NUMDIGS (x
);
1381 t2
= (SCM_BIGUP (t2
) + ds
[nd
]) % z
;
1384 return SCM_MAKINUM (sgn
? -t2
: t2
);
1387 #ifndef SCM_DIGSTOOBIG
1388 unsigned long t2
= scm_pseudolong (z
);
1389 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
1390 (SCM_BIGDIG
*) & t2
, SCM_DIGSPERLONG
,
1393 SCM_BIGDIG t2
[SCM_DIGSPERLONG
];
1394 scm_longdigs (z
, t2
);
1395 return scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
1396 t2
, SCM_DIGSPERLONG
,
1404 scm_divbigbig (SCM_BIGDIG
*x
, scm_sizet nx
, SCM_BIGDIG
*y
, scm_sizet ny
, int sgn
, int modes
)
1406 /* modes description
1410 3 quotient but returns 0 if division is not exact. */
1411 scm_sizet i
= 0, j
= 0;
1413 unsigned long t2
= 0;
1415 SCM_BIGDIG d
= 0, qhat
, *zds
, *yds
;
1416 /* algorithm requires nx >= ny */
1420 case 0: /* remainder -- just return x */
1421 z
= scm_mkbig (nx
, sgn
);
1422 zds
= SCM_BDIGITS (z
);
1429 case 1: /* scm_modulo -- return y-x */
1430 z
= scm_mkbig (ny
, sgn
);
1431 zds
= SCM_BDIGITS (z
);
1434 num
+= (long) y
[i
] - x
[i
];
1437 zds
[i
] = num
+ SCM_BIGRAD
;
1452 zds
[i
++] = num
+ SCM_BIGRAD
;
1463 return SCM_INUM0
; /* quotient is zero */
1465 return 0; /* the division is not exact */
1468 z
= scm_mkbig (nx
== ny
? nx
+ 2 : nx
+ 1, sgn
);
1469 zds
= SCM_BDIGITS (z
);
1473 ny
--; /* in case y came in as a psuedolong */
1474 if (y
[ny
- 1] < (SCM_BIGRAD
>> 1))
1475 { /* normalize operands */
1476 d
= SCM_BIGRAD
/ (y
[ny
- 1] + 1);
1477 newy
= scm_mkbig (ny
, 0);
1478 yds
= SCM_BDIGITS (newy
);
1481 t2
+= (unsigned long) y
[j
] * d
;
1482 yds
[j
++] = SCM_BIGLO (t2
);
1483 t2
= SCM_BIGDN (t2
);
1490 t2
+= (unsigned long) x
[j
] * d
;
1491 zds
[j
++] = SCM_BIGLO (t2
);
1492 t2
= SCM_BIGDN (t2
);
1502 j
= nx
== ny
? nx
+ 1 : nx
; /* dividend needs more digits than divisor */
1504 { /* loop over digits of quotient */
1505 if (zds
[j
] == y
[ny
- 1])
1506 qhat
= SCM_BIGRAD
- 1;
1508 qhat
= (SCM_BIGUP (zds
[j
]) + zds
[j
- 1]) / y
[ny
- 1];
1515 { /* multiply and subtract */
1516 t2
+= (unsigned long) y
[i
] * qhat
;
1517 num
+= zds
[j
- ny
+ i
] - SCM_BIGLO (t2
);
1520 zds
[j
- ny
+ i
] = num
+ SCM_BIGRAD
;
1525 zds
[j
- ny
+ i
] = num
;
1528 t2
= SCM_BIGDN (t2
);
1531 num
+= zds
[j
- ny
+ i
] - t2
; /* borrow from high digit; don't update */
1533 { /* "add back" required */
1539 num
+= (long) zds
[j
- ny
+ i
] + y
[i
];
1540 zds
[j
- ny
+ i
] = SCM_BIGLO (num
);
1541 num
= SCM_BIGDN (num
);
1552 case 3: /* check that remainder==0 */
1553 for (j
= ny
; j
&& !zds
[j
- 1]; --j
);
1556 case 2: /* move quotient down in z */
1557 j
= (nx
== ny
? nx
+ 2 : nx
+ 1) - ny
;
1558 for (i
= 0; i
< j
; i
++)
1559 zds
[i
] = zds
[i
+ ny
];
1562 case 1: /* subtract for scm_modulo */
1568 num
+= y
[i
] - zds
[i
];
1572 zds
[i
] = num
+ SCM_BIGRAD
;
1584 case 0: /* just normalize remainder */
1586 scm_divbigdig (zds
, ny
, d
);
1589 for (j
= ny
; j
&& !zds
[j
- 1]; --j
);
1590 if (j
* SCM_BITSPERDIG
<= sizeof (SCM
) * SCM_CHAR_BIT
)
1591 if (SCM_INUMP (z
= scm_big2inum (z
, j
)))
1593 return scm_adjbig (z
, j
);
1601 /*** NUMBERS -> STRINGS ***/
1604 static const double fx
[] =
1605 { 0.0, 5e-1, 5e-2, 5e-3, 5e-4, 5e-5,
1606 5e-6, 5e-7, 5e-8, 5e-9, 5e-10,
1607 5e-11, 5e-12, 5e-13, 5e-14, 5e-15,
1608 5e-16, 5e-17, 5e-18, 5e-19, 5e-20};
1614 idbl2str (double f
, char *a
)
1616 int efmt
, dpt
, d
, i
, wp
= scm_dblprec
;
1621 goto zero
; /*{a[0]='0'; a[1]='.'; a[2]='0'; return 3;} */
1640 #ifdef DBL_MIN_10_EXP /* Prevent unnormalized values, as from
1641 make-uniform-vector, from causing infinite loops. */
1645 if (exp
-- < DBL_MIN_10_EXP
)
1651 if (exp
++ > DBL_MAX_10_EXP
)
1666 if (f
+ fx
[wp
] >= 10.0)
1673 dpt
= (exp
+ 9999) % 3;
1677 efmt
= (exp
< -3) || (exp
> wp
+ 2);
1702 if (f
+ fx
[wp
] >= 1.0)
1716 if ((dpt
> 4) && (exp
> 6))
1718 d
= (a
[0] == '-' ? 2 : 1);
1719 for (i
= ch
++; i
> d
; i
--)
1732 if (a
[ch
- 1] == '.')
1733 a
[ch
++] = '0'; /* trailing zero */
1742 for (i
= 10; i
<= exp
; i
*= 10);
1743 for (i
/= 10; i
; i
/= 10)
1745 a
[ch
++] = exp
/ i
+ '0';
1754 iflo2str (SCM flt
, char *str
)
1758 if (SCM_SINGP (flt
))
1759 i
= idbl2str (SCM_FLO (flt
), str
);
1762 i
= idbl2str (SCM_REAL (flt
), str
);
1763 if (SCM_CPLXP (flt
))
1765 if (0 <= SCM_IMAG (flt
)) /* jeh */
1766 str
[i
++] = '+'; /* jeh */
1767 i
+= idbl2str (SCM_IMAG (flt
), &str
[i
]);
1772 #endif /* SCM_FLOATS */
1774 /* convert a long to a string (unterminated). returns the number of
1775 characters in the result.
1777 p is destination: worst case (base 2) is SCM_INTBUFLEN */
1779 scm_iint2str (long num
, int rad
, char *p
)
1783 unsigned long n
= (num
< 0) ? -num
: num
;
1785 for (n
/= rad
; n
> 0; n
/= rad
)
1802 p
[i
] = d
+ ((d
< 10) ? '0' : 'a' - 10);
1811 big2str (SCM b
, unsigned int radix
)
1813 SCM t
= scm_copybig (b
, 0); /* sign of temp doesn't matter */
1814 register SCM_BIGDIG
*ds
= SCM_BDIGITS (t
);
1815 scm_sizet i
= SCM_NUMDIGS (t
);
1816 scm_sizet j
= radix
== 16 ? (SCM_BITSPERDIG
* i
) / 4 + 2
1817 : radix
>= 10 ? (SCM_BITSPERDIG
* i
* 241L) / 800 + 2
1818 : (SCM_BITSPERDIG
* i
) + 2;
1820 scm_sizet radct
= 0;
1821 scm_sizet ch
; /* jeh */
1822 SCM_BIGDIG radpow
= 1, radmod
= 0;
1823 SCM ss
= scm_makstr ((long) j
, 0);
1824 char *s
= SCM_CHARS (ss
), c
;
1825 while ((long) radpow
* radix
< SCM_BIGRAD
)
1830 s
[0] = scm_tc16_bigneg
== SCM_TYP16 (b
) ? '-' : '+';
1831 while ((i
|| radmod
) && j
)
1835 radmod
= (SCM_BIGDIG
) scm_divbigdig (ds
, i
, radpow
);
1843 s
[--j
] = c
< 10 ? c
+ '0' : c
+ 'a' - 10;
1845 ch
= s
[0] == '-' ? 1 : 0; /* jeh */
1848 for (i
= j
; j
< SCM_LENGTH (ss
); j
++)
1849 s
[ch
+ j
- i
] = s
[j
]; /* jeh */
1850 scm_vector_set_length_x (ss
, /* jeh */
1851 (SCM
) SCM_MAKINUM (ch
+ SCM_LENGTH (ss
) - i
));
1854 return scm_return_first (ss
, t
);
1859 SCM_DEFINE (scm_number_to_string
, "number->string", 1, 1, 0,
1862 #define FUNC_NAME s_scm_number_to_string
1865 SCM_VALIDATE_INUM_MIN_DEF_COPY(2,radix
,2,10,base
);
1869 char num_buf
[SCM_FLOBUFLEN
];
1871 SCM_ASRTGO (SCM_NIMP (x
), badx
);
1873 return big2str (x
, (unsigned int) base
);
1874 #ifndef SCM_RECKLESS
1882 SCM_ASSERT (SCM_INEXP (x
),
1883 x
, SCM_ARG1
, s_number_to_string
);
1885 return scm_makfromstr (num_buf
, iflo2str (x
, num_buf
), 0);
1891 SCM_ASSERT (SCM_BIGP (x
),
1892 x
, SCM_ARG1
, s_number_to_string
);
1893 return big2str (x
, (unsigned int) base
);
1896 SCM_ASSERT (SCM_INUMP (x
), x
, SCM_ARG1
, s_number_to_string
);
1900 char num_buf
[SCM_INTBUFLEN
];
1901 return scm_makfromstr (num_buf
,
1902 scm_iint2str (SCM_INUM (x
),
1911 /* These print routines are stubbed here so that scm_repl.c doesn't need
1912 SCM_FLOATS or SCM_BIGDIGs conditionals */
1915 scm_floprint (SCM sexp
, SCM port
, scm_print_state
*pstate
)
1918 char num_buf
[SCM_FLOBUFLEN
];
1919 scm_lfwrite (num_buf
, iflo2str (sexp
, num_buf
), port
);
1921 scm_ipruk ("float", sexp
, port
);
1929 scm_bigprint (SCM exp
, SCM port
, scm_print_state
*pstate
)
1932 exp
= big2str (exp
, (unsigned int) 10);
1933 scm_lfwrite (SCM_CHARS (exp
), (scm_sizet
) SCM_LENGTH (exp
), port
);
1935 scm_ipruk ("bignum", exp
, port
);
1939 /*** END nums->strs ***/
1941 /*** STRINGS -> NUMBERS ***/
1944 scm_small_istr2int (char *str
, long len
, long radix
)
1946 register long n
= 0, ln
;
1951 return SCM_BOOL_F
; /* zero scm_length */
1953 { /* leading sign */
1958 return SCM_BOOL_F
; /* bad if lone `+' or `-' */
1963 switch (c
= str
[i
++])
1985 return SCM_BOOL_F
; /* bad digit for radix */
1988 /* Negation is a workaround for HP700 cc bug */
1989 if (n
> ln
|| (-n
> -SCM_MOST_NEGATIVE_FIXNUM
))
1993 return SCM_BOOL_F
; /* not a digit */
1998 if ((n
= -n
) > SCM_MOST_POSITIVE_FIXNUM
)
2000 return SCM_MAKINUM (n
);
2001 ovfl
: /* overflow scheme integer */
2008 scm_istr2int (char *str
, long len
, long radix
)
2011 register scm_sizet k
, blen
= 1;
2015 register SCM_BIGDIG
*ds
;
2016 register unsigned long t2
;
2019 return SCM_BOOL_F
; /* zero scm_length */
2021 /* Short numbers we parse directly into an int, to avoid the overhead
2022 of creating a bignum. */
2024 return scm_small_istr2int (str
, len
, radix
);
2027 j
= 1 + (4 * len
* sizeof (char)) / (SCM_BITSPERDIG
);
2028 else if (10 <= radix
)
2029 j
= 1 + (84 * len
* sizeof (char)) / (SCM_BITSPERDIG
* 25);
2031 j
= 1 + (len
* sizeof (char)) / (SCM_BITSPERDIG
);
2033 { /* leading sign */
2036 if (++i
== (unsigned) len
)
2037 return SCM_BOOL_F
; /* bad if lone `+' or `-' */
2039 res
= scm_mkbig (j
, '-' == str
[0]);
2040 ds
= SCM_BDIGITS (res
);
2045 switch (c
= str
[i
++])
2067 return SCM_BOOL_F
; /* bad digit for radix */
2073 /* printf ("k = %d, blen = %d, t2 = %ld, ds[k] = %d\n", k, blen, t2, ds[k]); */
2074 t2
+= ds
[k
] * radix
;
2075 ds
[k
++] = SCM_BIGLO (t2
);
2076 t2
= SCM_BIGDN (t2
);
2079 scm_num_overflow ("bignum");
2087 return SCM_BOOL_F
; /* not a digit */
2090 while (i
< (unsigned) len
);
2091 if (blen
* SCM_BITSPERDIG
/ SCM_CHAR_BIT
<= sizeof (SCM
))
2092 if (SCM_INUMP (res
= scm_big2inum (res
, blen
)))
2096 return scm_adjbig (res
, blen
);
2102 scm_istr2flo (char *str
, long len
, long radix
)
2104 register int c
, i
= 0;
2106 double res
= 0.0, tmp
= 0.0;
2112 return SCM_BOOL_F
; /* zero scm_length */
2115 { /* leading sign */
2128 return SCM_BOOL_F
; /* bad if lone `+' or `-' */
2130 if (str
[i
] == 'i' || str
[i
] == 'I')
2131 { /* handle `+i' and `-i' */
2132 if (lead_sgn
== 0.0)
2133 return SCM_BOOL_F
; /* must have leading sign */
2135 return SCM_BOOL_F
; /* `i' not last character */
2136 return scm_makdbl (0.0, lead_sgn
);
2139 { /* check initial digits */
2149 goto out1
; /* must be exponent */
2166 return SCM_BOOL_F
; /* bad digit for radix */
2167 res
= res
* radix
+ c
;
2168 flg
= 1; /* res is valid */
2177 /* if true, then we did see a digit above, and res is valid */
2181 /* By here, must have seen a digit,
2182 or must have next char be a `.' with radix==10 */
2184 if (!(str
[i
] == '.' && radix
== 10))
2187 while (str
[i
] == '#')
2188 { /* optional sharps */
2221 tmp
= tmp
* radix
+ c
;
2229 return SCM_BOOL_F
; /* `slash zero' not allowed */
2231 while (str
[i
] == '#')
2232 { /* optional sharps */
2242 { /* decimal point notation */
2244 return SCM_BOOL_F
; /* must be radix 10 */
2251 res
= res
* 10.0 + c
- '0';
2260 return SCM_BOOL_F
; /* no digits before or after decimal point */
2263 while (str
[i
] == '#')
2264 { /* ignore remaining sharps */
2283 int expsgn
= 1, expon
= 0;
2285 return SCM_BOOL_F
; /* only in radix 10 */
2287 return SCM_BOOL_F
; /* bad exponent */
2294 return SCM_BOOL_F
; /* bad exponent */
2296 if (str
[i
] < '0' || str
[i
] > '9')
2297 return SCM_BOOL_F
; /* bad exponent */
2303 expon
= expon
* 10 + c
- '0';
2305 return SCM_BOOL_F
; /* exponent too large */
2313 point
+= expsgn
* expon
;
2331 /* at this point, we have a legitimate floating point result */
2332 if (lead_sgn
== -1.0)
2335 return scm_makdbl (res
, 0.0);
2337 if (str
[i
] == 'i' || str
[i
] == 'I')
2338 { /* pure imaginary number */
2339 if (lead_sgn
== 0.0)
2340 return SCM_BOOL_F
; /* must have leading sign */
2342 return SCM_BOOL_F
; /* `i' not last character */
2343 return scm_makdbl (0.0, res
);
2355 { /* polar input for complex number */
2356 /* get a `real' for scm_angle */
2357 second
= scm_istr2flo (&str
[i
], (long) (len
- i
), radix
);
2358 if (!SCM_INEXP (second
))
2359 return SCM_BOOL_F
; /* not `real' */
2360 if (SCM_CPLXP (second
))
2361 return SCM_BOOL_F
; /* not `real' */
2362 tmp
= SCM_REALPART (second
);
2363 return scm_makdbl (res
* cos (tmp
), res
* sin (tmp
));
2369 /* at this point, last char must be `i' */
2370 if (str
[len
- 1] != 'i' && str
[len
- 1] != 'I')
2372 /* handles `x+i' and `x-i' */
2374 return scm_makdbl (res
, lead_sgn
);
2375 /* get a `ureal' for complex part */
2376 second
= scm_istr2flo (&str
[i
], (long) ((len
- i
) - 1), radix
);
2377 if (!SCM_INEXP (second
))
2378 return SCM_BOOL_F
; /* not `ureal' */
2379 if (SCM_CPLXP (second
))
2380 return SCM_BOOL_F
; /* not `ureal' */
2381 tmp
= SCM_REALPART (second
);
2383 return SCM_BOOL_F
; /* not `ureal' */
2384 return scm_makdbl (res
, (lead_sgn
* tmp
));
2386 #endif /* SCM_FLOATS */
2391 scm_istring2number (char *str
, long len
, long radix
)
2395 char ex_p
= 0, rx_p
= 0; /* Only allow 1 exactness and 1 radix prefix */
2398 if (*str
== '+' || *str
== '-') /* Catches lone `+' and `-' for speed */
2401 while ((len
- i
) >= 2 && str
[i
] == '#' && ++i
)
2447 return scm_istr2int (&str
[i
], len
- i
, radix
);
2449 res
= scm_istr2int (&str
[i
], len
- i
, radix
);
2450 if (SCM_NFALSEP (res
))
2454 return scm_istr2flo (&str
[i
], len
- i
, radix
);
2461 SCM_DEFINE (scm_string_to_number
, "string->number", 1, 1, 0,
2462 (SCM str
, SCM radix
),
2464 #define FUNC_NAME s_scm_string_to_number
2468 SCM_VALIDATE_ROSTRING(1,str
);
2469 SCM_VALIDATE_INUM_MIN_DEF_COPY(2,radix
,2,10,base
);
2470 answer
= scm_istring2number (SCM_ROCHARS (str
),
2473 return scm_return_first (answer
, str
);
2476 /*** END strs->nums ***/
2481 scm_makdbl (double x
, double y
)
2484 if ((y
== 0.0) && (x
== 0.0))
2491 #ifndef SCM_SINGLESONLY
2492 if ((-FLTMAX
< x
) && (x
< FLTMAX
) && (fx
== x
))
2495 SCM_NEWSMOB(z
,scm_tc_flo
,NULL
);
2500 #endif /* def SCM_SINGLES */
2501 SCM_NEWSMOB(z
,scm_tc_dblr
,scm_must_malloc (1L * sizeof (double), "real"));
2505 SCM_NEWSMOB(z
,scm_tc_dblc
,scm_must_malloc (2L * sizeof (double), "comkplex"));
2517 scm_bigequal (SCM x
, SCM y
)
2520 if (0 == scm_bigcomp (x
, y
))
2529 scm_floequal (SCM x
, SCM y
)
2532 if (SCM_REALPART (x
) != SCM_REALPART (y
))
2534 if (!(SCM_CPLXP (x
) && (SCM_IMAG (x
) != SCM_IMAG (y
))))
2543 SCM_REGISTER_PROC (s_number_p
, "number?", 1, 0, 0, scm_number_p
);
2545 SCM_DEFINE (scm_number_p
, "complex?", 1, 0, 0,
2548 #define FUNC_NAME s_scm_number_p
2568 SCM_REGISTER_PROC (s_real_p
, "real?", 1, 0, 0, scm_real_p
);
2571 SCM_DEFINE (scm_real_p
, "rational?", 1, 0, 0,
2574 #define FUNC_NAME s_scm_real_p
2592 SCM_DEFINE (scm_integer_p
, "integer?", 1, 0, 0,
2595 #define FUNC_NAME s_scm_integer_p
2610 r
= SCM_REALPART (x
);
2619 #endif /* SCM_FLOATS */
2621 SCM_DEFINE (scm_inexact_p
, "inexact?", 1, 0, 0,
2624 #define FUNC_NAME s_scm_inexact_p
2637 SCM_GPROC1 (s_eq_p
, "=", scm_tc7_rpsubr
, scm_num_eq_p
, g_eq_p
);
2640 scm_num_eq_p (SCM x
, SCM y
)
2650 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2656 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2658 return SCM_BOOL(0 == scm_bigcomp (x
, y
));
2659 SCM_ASRTGO (SCM_INEXP (y
), bady
);
2661 return ((SCM_REALP (y
) && (scm_big2dbl (x
) == SCM_REALPART (y
)))
2665 SCM_ASRTGO (SCM_INEXP (x
), badx
);
2667 SCM_GASSERT2 (SCM_INEXP (x
),
2668 g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2678 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2686 SCM_ASRTGO (SCM_INEXP (y
), bady
);
2688 SCM_ASRTGO (SCM_INEXP (y
), bady
);
2690 if (SCM_REALPART (x
) != SCM_REALPART (y
))
2693 return ((SCM_CPLXP (y
) && (SCM_IMAG (x
) == SCM_IMAG (y
)))
2696 return SCM_NEGATE_BOOL(SCM_CPLXP (y
));
2701 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2707 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2713 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2717 return ((SCM_REALP (y
) && (((double) SCM_INUM (x
)) == SCM_REALPART (y
)))
2725 SCM_GASSERT2 (SCM_BIGP (x
),
2726 g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2729 SCM_ASRTGO (SCM_BIGP (y
), bady
);
2730 return SCM_BOOL(0 == scm_bigcomp (x
, y
));
2737 SCM_WTA_DISPATCH_2 (g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2742 SCM_GASSERT2 (SCM_INUMP (x
), g_eq_p
, x
, y
, SCM_ARG1
, s_eq_p
);
2743 SCM_GASSERT2 (SCM_INUMP (y
), g_eq_p
, x
, y
, SCM_ARGn
, s_eq_p
);
2746 return SCM_BOOL((long) x
== (long) y
);
2751 SCM_GPROC1 (s_less_p
, "<", scm_tc7_rpsubr
, scm_less_p
, g_less_p
);
2754 scm_less_p (SCM x
, SCM y
)
2763 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2768 return SCM_BOOL(SCM_BIGSIGN (x
));
2769 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2771 return SCM_BOOL(1 == scm_bigcomp (x
, y
));
2772 SCM_ASRTGO (SCM_REALP (y
), bady
);
2773 return ((scm_big2dbl (x
) < SCM_REALPART (y
))
2777 SCM_ASRTGO (SCM_REALP (x
), badx
);
2779 SCM_GASSERT2 (SCM_REALP (x
),
2780 g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2783 return ((SCM_REALPART (x
) < ((double) SCM_INUM (y
)))
2787 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2789 return SCM_BOOL(SCM_REALPART (x
) < scm_big2dbl (y
));
2790 SCM_ASRTGO (SCM_REALP (y
), bady
);
2792 SCM_ASRTGO (SCM_REALP (y
), bady
);
2794 return SCM_BOOL(SCM_REALPART (x
) < SCM_REALPART (y
));
2799 SCM_ASRTGO (SCM_NIMP (y
), bady
);
2801 return SCM_NEGATE_BOOL(SCM_BIGSIGN (y
));
2805 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2811 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2814 return ((((double) SCM_INUM (x
)) < SCM_REALPART (y
))
2822 SCM_GASSERT2 (SCM_BIGP (x
),
2823 g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2825 return SCM_BOOL(SCM_BIGSIGN (x
));
2826 SCM_ASRTGO (SCM_BIGP (y
), bady
);
2827 return SCM_BOOL(1 == scm_bigcomp (x
, y
));
2834 SCM_WTA_DISPATCH_2 (g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2836 return SCM_NEGATE_BOOL(SCM_BIGSIGN (y
));
2839 SCM_GASSERT2 (SCM_INUMP (x
), g_less_p
, x
, y
, SCM_ARG1
, s_less_p
);
2840 SCM_GASSERT2 (SCM_INUMP (y
), g_less_p
, x
, y
, SCM_ARGn
, s_less_p
);
2843 return SCM_BOOL((long) x
< (long) y
);
2847 GUILE_PROC1 (scm_gr_p
, ">", scm_tc7_rpsubr
,
2850 #define FUNC_NAME s_scm_gr_p
2852 return scm_less_p (y
, x
);
2858 GUILE_PROC1 (scm_leq_p
, "<=", scm_tc7_rpsubr
,
2861 #define FUNC_NAME s_scm_leq_p
2863 return SCM_BOOL_NOT (scm_less_p (y
, x
));
2869 GUILE_PROC1 (scm_geq_p
, ">=", scm_tc7_rpsubr
,
2872 #define FUNC_NAME s_scm_geq_p
2874 return SCM_BOOL_NOT (scm_less_p (x
, y
));
2880 SCM_GPROC (s_zero_p
, "zero?", 1, 0, 0, scm_zero_p
, g_zero_p
);
2889 SCM_ASRTGO (SCM_NIMP (z
), badz
);
2895 SCM_WTA_DISPATCH_1 (g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2898 SCM_GASSERT1 (SCM_INEXP (z
),
2899 g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2901 return SCM_BOOL(z
== scm_flo0
);
2907 SCM_GASSERT1 (SCM_BIGP (z
),
2908 g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2912 SCM_GASSERT1 (SCM_INUMP (z
), g_zero_p
, z
, SCM_ARG1
, s_zero_p
);
2915 return SCM_BOOL(z
== SCM_INUM0
);
2920 SCM_GPROC (s_positive_p
, "positive?", 1, 0, 0, scm_positive_p
, g_positive_p
);
2923 scm_positive_p (SCM x
)
2929 SCM_ASRTGO (SCM_NIMP (x
), badx
);
2931 return SCM_BOOL(SCM_TYP16 (x
) == scm_tc16_bigpos
);
2935 SCM_WTA_DISPATCH_1 (g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2938 SCM_GASSERT1 (SCM_REALP (x
),
2939 g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2941 return SCM_BOOL(SCM_REALPART (x
) > 0.0);
2947 SCM_GASSERT1 (SCM_BIGP (x
),
2948 g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2949 return SCM_BOOL(SCM_TYP16 (x
) == scm_tc16_bigpos
);
2952 SCM_GASSERT1 (SCM_INUMP (x
), g_positive_p
, x
, SCM_ARG1
, s_positive_p
);
2955 return SCM_BOOL(x
> SCM_INUM0
);
2960 SCM_GPROC (s_negative_p
, "negative?", 1, 0, 0, scm_negative_p
, g_negative_p
);
2963 scm_negative_p (SCM x
)
2969 SCM_ASRTGO (SCM_NIMP (x
), badx
);
2971 return SCM_NEGATE_BOOL(SCM_TYP16 (x
) == scm_tc16_bigpos
);
2972 if (!(SCM_REALP (x
)))
2975 SCM_WTA_DISPATCH_1 (g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2978 SCM_GASSERT1 (SCM_REALP (x
),
2979 g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2981 return SCM_BOOL(SCM_REALPART (x
) < 0.0);
2987 SCM_GASSERT1 (SCM_BIGP (x
),
2988 g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2989 return SCM_BOOL(SCM_TYP16 (x
) == scm_tc16_bigneg
);
2992 SCM_GASSERT1 (SCM_INUMP (x
), g_negative_p
, x
, SCM_ARG1
, s_negative_p
);
2995 return SCM_BOOL(x
< SCM_INUM0
);
2999 SCM_GPROC1 (s_max
, "max", scm_tc7_asubr
, scm_max
, g_max
);
3002 scm_max (SCM x
, SCM y
)
3009 SCM_GASSERT0 (!SCM_UNBNDP (x
),
3010 g_max
, scm_makfrom0str (s_max
), SCM_WNA
, 0);
3011 SCM_GASSERT1 (SCM_NUMBERP (x
), g_max
, x
, SCM_ARG1
, s_max
);
3021 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARG1
, s_max
);
3026 return SCM_BIGSIGN (x
) ? y
: x
;
3027 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3029 return (1 == scm_bigcomp (x
, y
)) ? y
: x
;
3030 SCM_ASRTGO (SCM_REALP (y
), bady
);
3031 z
= scm_big2dbl (x
);
3032 return (z
< SCM_REALPART (y
)) ? y
: scm_makdbl (z
, 0.0);
3034 SCM_ASRTGO (SCM_REALP (x
), badx2
);
3036 SCM_GASSERT2 (SCM_REALP (x
),
3037 g_max
, x
, y
, SCM_ARG1
, s_max
);
3040 return ((SCM_REALPART (x
) < (z
= SCM_INUM (y
)))
3041 ? scm_makdbl (z
, 0.0)
3044 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3046 return ((SCM_REALPART (x
) < (z
= scm_big2dbl (y
)))
3047 ? scm_makdbl (z
, 0.0)
3049 SCM_ASRTGO (SCM_REALP (y
), bady
);
3051 SCM_ASRTGO (SCM_REALP (y
), bady
);
3053 return (SCM_REALPART (x
) < SCM_REALPART (y
)) ? y
: x
;
3058 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3060 return SCM_BIGSIGN (y
) ? x
: y
;
3061 if (!(SCM_REALP (y
)))
3064 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARGn
, s_max
);
3070 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARGn
, s_max
);
3073 return (((z
= SCM_INUM (x
)) < SCM_REALPART (y
))
3075 : scm_makdbl (z
, 0.0));
3081 SCM_GASSERT2 (SCM_BIGP (x
),
3082 g_max
, x
, y
, SCM_ARG1
, s_max
);
3084 return SCM_BIGSIGN (x
) ? y
: x
;
3085 SCM_ASRTGO (SCM_BIGP (y
), bady
);
3086 return (1 == scm_bigcomp (x
, y
)) ? y
: x
;
3093 SCM_WTA_DISPATCH_2 (g_max
, x
, y
, SCM_ARGn
, s_max
);
3095 return SCM_BIGSIGN (y
) ? x
: y
;
3098 SCM_GASSERT2 (SCM_INUMP (x
), g_max
, x
, y
, SCM_ARG1
, s_max
);
3099 SCM_GASSERT2 (SCM_INUMP (y
), g_max
, x
, y
, SCM_ARGn
, s_max
);
3102 return ((long) x
< (long) y
) ? y
: x
;
3108 SCM_GPROC1 (s_min
, "min", scm_tc7_asubr
, scm_min
, g_min
);
3111 scm_min (SCM x
, SCM y
)
3118 SCM_GASSERT0 (!SCM_UNBNDP (x
),
3119 g_min
, scm_makfrom0str (s_min
), SCM_WNA
, 0);
3120 SCM_GASSERT1 (SCM_NUMBERP (x
), g_min
, x
, SCM_ARG1
, s_min
);
3130 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARG1
, s_min
);
3135 return SCM_BIGSIGN (x
) ? x
: y
;
3136 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3138 return (-1 == scm_bigcomp (x
, y
)) ? y
: x
;
3139 SCM_ASRTGO (SCM_REALP (y
), bady
);
3140 z
= scm_big2dbl (x
);
3141 return (z
> SCM_REALPART (y
)) ? y
: scm_makdbl (z
, 0.0);
3143 SCM_ASRTGO (SCM_REALP (x
), badx2
);
3145 SCM_GASSERT2 (SCM_REALP (x
),
3146 g_min
, x
, y
, SCM_ARG1
, s_min
);
3149 return ((SCM_REALPART (x
) > (z
= SCM_INUM (y
)))
3150 ? scm_makdbl (z
, 0.0)
3153 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3155 return ((SCM_REALPART (x
) > (z
= scm_big2dbl (y
)))
3156 ? scm_makdbl (z
, 0.0)
3158 SCM_ASRTGO (SCM_REALP (y
), bady
);
3160 SCM_ASRTGO (SCM_REALP (y
), bady
);
3162 return (SCM_REALPART (x
) > SCM_REALPART (y
)) ? y
: x
;
3167 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3169 return SCM_BIGSIGN (y
) ? y
: x
;
3170 if (!(SCM_REALP (y
)))
3173 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARGn
, s_min
);
3179 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARGn
, s_min
);
3182 return (((z
= SCM_INUM (x
)) > SCM_REALPART (y
))
3184 : scm_makdbl (z
, 0.0));
3190 SCM_GASSERT2 (SCM_BIGP (x
),
3191 g_min
, x
, y
, SCM_ARG1
, s_min
);
3193 return SCM_BIGSIGN (x
) ? x
: y
;
3194 SCM_ASRTGO (SCM_BIGP (y
), bady
);
3195 return (-1 == scm_bigcomp (x
, y
)) ? y
: x
;
3202 SCM_WTA_DISPATCH_2 (g_min
, x
, y
, SCM_ARGn
, s_min
);
3204 return SCM_BIGSIGN (y
) ? y
: x
;
3207 SCM_GASSERT2 (SCM_INUMP (x
), g_min
, x
, y
, SCM_ARG1
, s_min
);
3208 SCM_GASSERT2 (SCM_INUMP (y
), g_min
, x
, y
, SCM_ARGn
, s_min
);
3211 return ((long) x
> (long) y
) ? y
: x
;
3217 SCM_GPROC1 (s_sum
, "+", scm_tc7_asubr
, scm_sum
, g_sum
);
3220 scm_sum (SCM x
, SCM y
)
3226 SCM_GASSERT1 (SCM_NUMBERP (x
), g_sum
, x
, SCM_ARG1
, s_sum
);
3237 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARG1
, s_sum
);
3248 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3251 if (SCM_NUMDIGS (x
) > SCM_NUMDIGS (y
))
3257 return scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3261 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3263 return scm_makdbl (scm_big2dbl (x
) + SCM_REALPART (y
),
3264 SCM_CPLXP (y
) ? SCM_IMAG (y
) : 0.0);
3266 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3268 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3278 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3286 else if (!SCM_INEXP (y
))
3289 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3295 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3304 return scm_makdbl (SCM_REALPART (x
) + SCM_REALPART (y
), i
);
3310 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3315 #ifndef SCM_DIGSTOOBIG
3316 long z
= scm_pseudolong (SCM_INUM (x
));
3317 return scm_addbig ((SCM_BIGDIG
*) & z
,
3319 (x
< 0) ? 0x0100 : 0,
3322 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3323 scm_longdigs (SCM_INUM (x
), zdigs
);
3324 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3329 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3331 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3334 return scm_makdbl (SCM_INUM (x
) + SCM_REALPART (y
),
3335 SCM_CPLXP (y
) ? SCM_IMAG (y
) : 0.0);
3342 SCM_ASRTGO (SCM_BIGP (x
), badx2
);
3350 SCM_ASRTGO (SCM_BIGP (y
), bady
);
3351 if (SCM_NUMDIGS (x
) > SCM_NUMDIGS (y
))
3357 return scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
), SCM_BIGSIGN (x
),
3365 SCM_WTA_DISPATCH_2 (g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3369 #ifndef SCM_DIGSTOOBIG
3370 long z
= scm_pseudolong (SCM_INUM (x
));
3371 return scm_addbig (&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
3373 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3374 scm_longdigs (SCM_INUM (x
), zdigs
);
3375 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0, y
, 0);
3380 SCM_ASRTGO (SCM_INUMP (x
), badx2
);
3381 SCM_GASSERT2 (SCM_INUMP (y
), g_sum
, x
, y
, SCM_ARGn
, s_sum
);
3384 x
= SCM_INUM (x
) + SCM_INUM (y
);
3385 if (SCM_FIXABLE (x
))
3386 return SCM_MAKINUM (x
);
3388 return scm_long2big (x
);
3391 return scm_makdbl ((double) x
, 0.0);
3393 scm_num_overflow (s_sum
);
3394 return SCM_UNSPECIFIED
;
3402 SCM_GPROC1 (s_difference
, "-", scm_tc7_asubr
, scm_difference
, g_difference
);
3405 scm_difference (SCM x
, SCM y
)
3410 if (!(SCM_NIMP (x
)))
3414 SCM_GASSERT0 (!SCM_UNBNDP (x
), g_difference
,
3415 scm_makfrom0str (s_difference
), SCM_WNA
, 0);
3417 SCM_WTA_DISPATCH_1 (g_difference
, x
, SCM_ARG1
, s_difference
);
3422 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARG1
, s_difference
);
3430 x
= scm_copybig (x
, !SCM_BIGSIGN (x
));
3431 return (SCM_NUMDIGS (x
) * SCM_BITSPERDIG
/ SCM_CHAR_BIT
3433 ? scm_big2inum (x
, SCM_NUMDIGS (x
))
3437 SCM_ASRTGO (SCM_INEXP (x
), badx
);
3438 return scm_makdbl (- SCM_REALPART (x
),
3439 SCM_CPLXP (x
) ? -SCM_IMAG (x
) : 0.0);
3442 return scm_sum (x
, SCM_MAKINUM (- SCM_INUM (y
)));
3444 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3448 return ((SCM_NUMDIGS (x
) < SCM_NUMDIGS (y
))
3449 ? scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3452 : scm_addbig (SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3453 SCM_BIGSIGN (y
) ^ 0x0100,
3455 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3456 return scm_makdbl (scm_big2dbl (x
) - SCM_REALPART (y
),
3457 SCM_CPLXP (y
) ? -SCM_IMAG (y
) : 0.0);
3459 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3461 return scm_makdbl (SCM_REALPART (x
) - scm_big2dbl (y
),
3462 SCM_CPLXP (x
) ? SCM_IMAG (x
) : 0.0);
3463 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3465 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3466 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3471 return scm_makdbl (SCM_REAL (x
) - SCM_REAL (y
),
3472 SCM_IMAG (x
) - SCM_IMAG (y
));
3474 return scm_makdbl (SCM_REAL (x
) - SCM_REALPART (y
), SCM_IMAG (x
));
3476 return scm_makdbl (SCM_REALPART (x
) - SCM_REALPART (y
),
3477 SCM_CPLXP (y
) ? - SCM_IMAG (y
) : 0.0);
3487 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3490 #ifndef SCM_DIGSTOOBIG
3491 long z
= scm_pseudolong (SCM_INUM (x
));
3492 return scm_addbig ((SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3493 (x
< 0) ? 0x0100 : 0,
3496 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3497 scm_longdigs (SCM_INUM (x
), zdigs
);
3498 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3505 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3511 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3514 return scm_makdbl (SCM_INUM (x
) - SCM_REALPART (y
),
3515 SCM_CPLXP (y
) ? -SCM_IMAG (y
) : 0.0);
3521 SCM_GASSERT2 (SCM_BIGP (x
),
3522 g_difference
, x
, y
, SCM_ARG1
, s_difference
);
3525 x
= scm_copybig (x
, !SCM_BIGSIGN (x
));
3526 return (SCM_NUMDIGS (x
) * SCM_BITSPERDIG
/ SCM_CHAR_BIT
3528 ? scm_big2inum (x
, SCM_NUMDIGS (x
))
3533 #ifndef SCM_DIGSTOOBIG
3534 long z
= scm_pseudolong (SCM_INUM (y
));
3535 return scm_addbig (&z
, SCM_DIGSPERLONG
, (y
< 0) ? 0 : 0x0100, x
, 0);
3537 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3538 scm_longdigs (SCM_INUM (x
), zdigs
);
3539 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (y
< 0) ? 0 : 0x0100,
3543 SCM_ASRTGO (SCM_BIGP (y
), bady
);
3544 return (SCM_NUMDIGS (x
) < SCM_NUMDIGS (y
)) ?
3545 scm_addbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
), SCM_BIGSIGN (x
),
3547 scm_addbig (SCM_BDIGITS (y
), SCM_NUMDIGS (y
), SCM_BIGSIGN (y
) ^ 0x0100,
3560 SCM_WTA_DISPATCH_2 (g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3563 #ifndef SCM_DIGSTOOBIG
3564 long z
= scm_pseudolong (SCM_INUM (x
));
3565 return scm_addbig (&z
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3568 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3569 scm_longdigs (SCM_INUM (x
), zdigs
);
3570 return scm_addbig (zdigs
, SCM_DIGSPERLONG
, (x
< 0) ? 0x0100 : 0,
3576 SCM_GASSERT2 (SCM_INUMP (x
), g_difference
, x
, y
, SCM_ARG1
, s_difference
);
3582 SCM_GASSERT2 (SCM_INUMP (y
), g_difference
, x
, y
, SCM_ARGn
, s_difference
);
3585 x
= SCM_INUM (x
) - SCM_INUM (y
);
3587 if (SCM_FIXABLE (x
))
3588 return SCM_MAKINUM (x
);
3590 return scm_long2big (x
);
3593 return scm_makdbl ((double) x
, 0.0);
3595 scm_num_overflow (s_difference
);
3596 return SCM_UNSPECIFIED
;
3604 SCM_GPROC1 (s_product
, "*", scm_tc7_asubr
, scm_product
, g_product
);
3607 scm_product (SCM x
, SCM y
)
3612 return SCM_MAKINUM (1L);
3613 SCM_GASSERT1 (SCM_NUMBERP (x
), g_product
, x
, SCM_ARG1
, s_product
);
3624 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARG1
, s_product
);
3635 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3637 return scm_mulbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3638 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3639 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
));
3640 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3643 double bg
= scm_big2dbl (x
);
3644 return scm_makdbl (bg
* SCM_REALPART (y
),
3645 SCM_CPLXP (y
) ? bg
* SCM_IMAG (y
) : 0.0);
3648 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3650 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3660 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3668 else if (!(SCM_INEXP (y
)))
3671 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARGn
, s_product
);
3677 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARGn
, s_product
);
3683 return scm_makdbl (SCM_REAL (x
) * SCM_REAL (y
)
3684 - SCM_IMAG (x
) * SCM_IMAG (y
),
3685 SCM_REAL (x
) * SCM_IMAG (y
)
3686 + SCM_IMAG (x
) * SCM_REAL (y
));
3688 return scm_makdbl (SCM_REAL (x
) * SCM_REALPART (y
),
3689 SCM_IMAG (x
) * SCM_REALPART (y
));
3691 return scm_makdbl (SCM_REALPART (x
) * SCM_REALPART (y
),
3693 ? SCM_REALPART (x
) * SCM_IMAG (y
)
3699 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3705 if (SCM_MAKINUM (1L) == x
)
3708 #ifndef SCM_DIGSTOOBIG
3709 long z
= scm_pseudolong (SCM_INUM (x
));
3710 return scm_mulbig ((SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3711 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3712 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3714 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3715 scm_longdigs (SCM_INUM (x
), zdigs
);
3716 return scm_mulbig (zdigs
, SCM_DIGSPERLONG
,
3717 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3718 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3722 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3724 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3727 return scm_makdbl (SCM_INUM (x
) * SCM_REALPART (y
),
3728 SCM_CPLXP (y
) ? SCM_INUM (x
) * SCM_IMAG (y
) : 0.0);
3734 SCM_ASRTGO (SCM_BIGP (x
), badx2
);
3742 SCM_ASRTGO (SCM_BIGP (y
), bady
);
3743 return scm_mulbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3744 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3745 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
));
3752 SCM_WTA_DISPATCH_2 (g_product
, x
, y
, SCM_ARGn
, s_product
);
3757 if (SCM_MAKINUM (1L) == x
)
3760 #ifndef SCM_DIGSTOOBIG
3761 long z
= scm_pseudolong (SCM_INUM (x
));
3762 return scm_mulbig (&z
, SCM_DIGSPERLONG
,
3763 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3764 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3766 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3767 scm_longdigs (SCM_INUM (x
), zdigs
);
3768 return scm_mulbig (zdigs
, SCM_DIGSPERLONG
,
3769 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3770 SCM_BIGSIGN (y
) ? (x
> 0) : (x
< 0));
3775 SCM_ASRTGO (SCM_INUMP (x
), badx2
);
3776 SCM_GASSERT (SCM_INUMP (y
), g_product
, x
, y
, SCM_ARGn
, s_product
);
3786 y
= SCM_MAKINUM (k
);
3787 if (k
!= SCM_INUM (y
) || k
/ i
!= j
)
3790 int sgn
= (i
< 0) ^ (j
< 0);
3791 #ifndef SCM_DIGSTOOBIG
3792 i
= scm_pseudolong (i
);
3793 j
= scm_pseudolong (j
);
3794 return scm_mulbig ((SCM_BIGDIG
*) & i
, SCM_DIGSPERLONG
,
3795 (SCM_BIGDIG
*) & j
, SCM_DIGSPERLONG
, sgn
);
3796 #else /* SCM_DIGSTOOBIG */
3797 SCM_BIGDIG idigs
[SCM_DIGSPERLONG
];
3798 SCM_BIGDIG jdigs
[SCM_DIGSPERLONG
];
3799 scm_longdigs (i
, idigs
);
3800 scm_longdigs (j
, jdigs
);
3801 return scm_mulbig (idigs
, SCM_DIGSPERLONG
,
3802 jdigs
, SCM_DIGSPERLONG
,
3808 return scm_makdbl (((double) i
) * ((double) j
), 0.0);
3810 scm_num_overflow (s_product
);
3820 scm_num2dbl (SCM a
, const char *why
)
3823 return (double) SCM_INUM (a
);
3825 SCM_ASSERT (SCM_NIMP (a
), a
, "wrong type argument", why
);
3827 return (SCM_REALPART (a
));
3830 return scm_big2dbl (a
);
3832 SCM_ASSERT (0, a
, "wrong type argument", why
);
3833 return SCM_UNSPECIFIED
;
3837 SCM_GPROC1 (s_divide
, "/", scm_tc7_asubr
, scm_divide
, g_divide
);
3840 scm_divide (SCM x
, SCM y
)
3846 if (!(SCM_NIMP (x
)))
3850 SCM_GASSERT0 (!SCM_UNBNDP (x
),
3851 g_divide
, scm_makfrom0str (s_divide
), SCM_WNA
, 0);
3853 SCM_WTA_DISPATCH_1 (g_divide
, x
, SCM_ARG1
, s_divide
);
3858 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARG1
, s_divide
);
3865 return scm_makdbl (1.0 / scm_big2dbl (x
), 0.0);
3867 SCM_ASRTGO (SCM_INEXP (x
), badx
);
3869 return scm_makdbl (1.0 / SCM_REALPART (x
), 0.0);
3873 return scm_makdbl (r
/ d
, -i
/ d
);
3882 #ifndef SCM_RECKLESS
3884 scm_num_overflow (s_divide
);
3892 SCM w
= scm_copybig (x
, SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0));
3893 return (scm_divbigdig (SCM_BDIGITS (w
), SCM_NUMDIGS (w
),
3895 ? scm_makdbl (scm_big2dbl (x
) / SCM_INUM (y
), 0.0)
3898 #ifndef SCM_DIGSTOOBIG
3899 z
= scm_pseudolong (z
);
3900 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3901 (SCM_BIGDIG
*) & z
, SCM_DIGSPERLONG
,
3902 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
3905 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
3906 scm_longdigs (z
, zdigs
);
3907 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3908 zdigs
, SCM_DIGSPERLONG
,
3909 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
3912 return z
? z
: scm_makdbl (scm_big2dbl (x
) / SCM_INUM (y
), 0.0);
3914 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3917 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
3918 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
3919 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
), 3);
3920 return z
? z
: scm_makdbl (scm_big2dbl (x
) / scm_big2dbl (y
),
3923 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3925 return scm_makdbl (scm_big2dbl (x
) / SCM_REALPART (y
), 0.0);
3926 a
= scm_big2dbl (x
);
3930 SCM_ASRTGO (SCM_INEXP (x
), badx2
);
3937 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3940 d
= scm_big2dbl (y
);
3943 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3945 SCM_ASRTGO (SCM_INEXP (y
), bady
);
3949 d
= SCM_REALPART (y
);
3951 return scm_makdbl (SCM_REALPART (x
) / d
,
3952 SCM_CPLXP (x
) ? SCM_IMAG (x
) / d
: 0.0);
3954 a
= SCM_REALPART (x
);
3960 return scm_makdbl ((a
* r
+ SCM_IMAG (x
) * i
) / d
,
3961 (SCM_IMAG (x
) * r
- a
* i
) / d
);
3965 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
3967 return scm_makdbl (1.0 / ((double) SCM_INUM (x
)), 0.0);
3972 SCM_ASRTGO (SCM_NIMP (y
), bady
);
3974 return scm_makdbl (SCM_INUM (x
) / scm_big2dbl (y
), 0.0);
3975 if (!(SCM_INEXP (y
)))
3978 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARGn
, s_divide
);
3984 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARGn
, s_divide
);
3988 return scm_makdbl (SCM_INUM (x
) / SCM_REALPART (y
), 0.0);
3994 return scm_makdbl ((a
* r
) / d
, (-a
* i
) / d
);
4001 SCM_GASSERT2 (SCM_BIGP (x
),
4002 g_divide
, x
, y
, SCM_ARG1
, s_divide
);
4016 SCM w
= scm_copybig (x
, SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0));
4017 if (scm_divbigdig (SCM_BDIGITS (w
), SCM_NUMDIGS (w
),
4022 #ifndef SCM_DIGSTOOBIG
4023 z
= scm_pseudolong (z
);
4024 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
4025 &z
, SCM_DIGSPERLONG
,
4026 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
4029 SCM_BIGDIG zdigs
[SCM_DIGSPERLONG
];
4030 scm_longdigs (z
, zdigs
);
4031 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
4032 zdigs
, SCM_DIGSPERLONG
,
4033 SCM_BIGSIGN (x
) ? (y
> 0) : (y
< 0), 3);
4039 SCM_ASRTGO (SCM_BIGP (y
), bady
);
4040 z
= scm_divbigbig (SCM_BDIGITS (x
), SCM_NUMDIGS (x
),
4041 SCM_BDIGITS (y
), SCM_NUMDIGS (y
),
4042 SCM_BIGSIGN (x
) ^ SCM_BIGSIGN (y
), 3);
4050 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
4059 SCM_WTA_DISPATCH_2 (g_divide
, x
, y
, SCM_ARGn
, s_divide
);
4064 SCM_GASSERT2 (SCM_INUMP (x
), g_divide
, x
, y
, SCM_ARG1
, s_divide
);
4067 if ((SCM_MAKINUM (1L) == x
) || (SCM_MAKINUM (-1L) == x
))
4071 SCM_GASSERT2 (SCM_INUMP (y
), g_divide
, x
, y
, SCM_ARGn
, s_divide
);
4075 long z
= SCM_INUM (y
);
4076 if ((0 == z
) || SCM_INUM (x
) % z
)
4078 z
= SCM_INUM (x
) / z
;
4079 if (SCM_FIXABLE (z
))
4080 return SCM_MAKINUM (z
);
4082 return scm_long2big (z
);
4086 return scm_makdbl (((double) SCM_INUM (x
)) / ((double) SCM_INUM (y
)), 0.0);
4089 scm_num_overflow (s_divide
);
4090 return SCM_UNSPECIFIED
;
4099 SCM_GPROC1 (s_asinh
, "$asinh", scm_tc7_cxr
, (SCM (*)()) scm_asinh
, g_asinh
);
4102 scm_asinh (double x
)
4104 return log (x
+ sqrt (x
* x
+ 1));
4110 SCM_GPROC1 (s_acosh
, "$acosh", scm_tc7_cxr
, (SCM (*)()) scm_acosh
, g_acosh
);
4113 scm_acosh (double x
)
4115 return log (x
+ sqrt (x
* x
- 1));
4121 SCM_GPROC1 (s_atanh
, "$atanh", scm_tc7_cxr
, (SCM (*)()) scm_atanh
, g_atanh
);
4124 scm_atanh (double x
)
4126 return 0.5 * log ((1 + x
) / (1 - x
));
4132 SCM_GPROC1 (s_truncate
, "truncate", scm_tc7_cxr
, (SCM (*)()) scm_truncate
, g_truncate
);
4135 scm_truncate (double x
)
4144 SCM_GPROC1 (s_round
, "round", scm_tc7_cxr
, (SCM (*)()) scm_round
, g_round
);
4147 scm_round (double x
)
4149 double plus_half
= x
+ 0.5;
4150 double result
= floor (plus_half
);
4151 /* Adjust so that the scm_round is towards even. */
4152 return (plus_half
== result
&& plus_half
/ 2 != floor (plus_half
/ 2))
4153 ? result
- 1 : result
;
4158 SCM_GPROC1 (s_exact_to_inexact
, "exact->inexact", scm_tc7_cxr
, (SCM (*)()) scm_exact_to_inexact
, g_exact_to_inexact
);
4161 scm_exact_to_inexact (double z
)
4167 SCM_GPROC1 (s_i_floor
, "floor", scm_tc7_cxr
, (SCM (*)()) floor
, g_i_floor
);
4168 SCM_GPROC1 (s_i_ceil
, "ceiling", scm_tc7_cxr
, (SCM (*)()) ceil
, g_i_ceil
);
4169 SCM_GPROC1 (s_i_sqrt
, "$sqrt", scm_tc7_cxr
, (SCM (*)()) sqrt
, g_i_sqrt
);
4170 SCM_GPROC1 (s_i_abs
, "$abs", scm_tc7_cxr
, (SCM (*)()) fabs
, g_i_abs
);
4171 SCM_GPROC1 (s_i_exp
, "$exp", scm_tc7_cxr
, (SCM (*)()) exp
, g_i_exp
);
4172 SCM_GPROC1 (s_i_log
, "$log", scm_tc7_cxr
, (SCM (*)()) log
, g_i_log
);
4173 SCM_GPROC1 (s_i_sin
, "$sin", scm_tc7_cxr
, (SCM (*)()) sin
, g_i_sin
);
4174 SCM_GPROC1 (s_i_cos
, "$cos", scm_tc7_cxr
, (SCM (*)()) cos
, g_i_cos
);
4175 SCM_GPROC1 (s_i_tan
, "$tan", scm_tc7_cxr
, (SCM (*)()) tan
, g_i_tan
);
4176 SCM_GPROC1 (s_i_asin
, "$asin", scm_tc7_cxr
, (SCM (*)()) asin
, g_i_asin
);
4177 SCM_GPROC1 (s_i_acos
, "$acos", scm_tc7_cxr
, (SCM (*)()) acos
, g_i_acos
);
4178 SCM_GPROC1 (s_i_atan
, "$atan", scm_tc7_cxr
, (SCM (*)()) atan
, g_i_atan
);
4179 SCM_GPROC1 (s_i_sinh
, "$sinh", scm_tc7_cxr
, (SCM (*)()) sinh
, g_i_sinh
);
4180 SCM_GPROC1 (s_i_cosh
, "$cosh", scm_tc7_cxr
, (SCM (*)()) cosh
, g_i_cosh
);
4181 SCM_GPROC1 (s_i_tanh
, "$tanh", scm_tc7_cxr
, (SCM (*)()) tanh
, g_i_tanh
);
4188 static void scm_two_doubles (SCM z1
,
4190 const char *sstring
,
4194 scm_two_doubles (SCM z1
, SCM z2
, const char *sstring
, struct dpair
*xy
)
4197 xy
->x
= SCM_INUM (z1
);
4201 SCM_ASRTGO (SCM_NIMP (z1
), badz1
);
4203 xy
->x
= scm_big2dbl (z1
);
4206 #ifndef SCM_RECKLESS
4207 if (!SCM_REALP (z1
))
4208 badz1
:scm_wta (z1
, (char *) SCM_ARG1
, sstring
);
4210 xy
->x
= SCM_REALPART (z1
);
4214 SCM_ASSERT (SCM_REALP (z1
), z1
, SCM_ARG1
, sstring
);
4215 xy
->x
= SCM_REALPART (z1
);
4220 xy
->y
= SCM_INUM (z2
);
4224 SCM_ASRTGO (SCM_NIMP (z2
), badz2
);
4226 xy
->y
= scm_big2dbl (z2
);
4229 #ifndef SCM_RECKLESS
4230 if (!(SCM_REALP (z2
)))
4231 badz2
:scm_wta (z2
, (char *) SCM_ARG2
, sstring
);
4233 xy
->y
= SCM_REALPART (z2
);
4237 SCM_ASSERT (SCM_REALP (z2
), z2
, SCM_ARG2
, sstring
);
4238 xy
->y
= SCM_REALPART (z2
);
4247 SCM_DEFINE (scm_sys_expt
, "$expt", 2, 0, 0,
4250 #define FUNC_NAME s_scm_sys_expt
4253 scm_two_doubles (z1
, z2
, FUNC_NAME
, &xy
);
4254 return scm_makdbl (pow (xy
.x
, xy
.y
), 0.0);
4260 SCM_DEFINE (scm_sys_atan2
, "$atan2", 2, 0, 0,
4263 #define FUNC_NAME s_scm_sys_atan2
4266 scm_two_doubles (z1
, z2
, FUNC_NAME
, &xy
);
4267 return scm_makdbl (atan2 (xy
.x
, xy
.y
), 0.0);
4273 SCM_DEFINE (scm_make_rectangular
, "make-rectangular", 2, 0, 0,
4276 #define FUNC_NAME s_scm_make_rectangular
4279 scm_two_doubles (z1
, z2
, FUNC_NAME
, &xy
);
4280 return scm_makdbl (xy
.x
, xy
.y
);
4286 SCM_DEFINE (scm_make_polar
, "make-polar", 2, 0, 0,
4289 #define FUNC_NAME s_scm_make_polar
4292 scm_two_doubles (z1
, z2
, FUNC_NAME
, &xy
);
4293 return scm_makdbl (xy
.x
* cos (xy
.y
), xy
.x
* sin (xy
.y
));
4300 SCM_GPROC (s_real_part
, "real-part", 1, 0, 0, scm_real_part
, g_real_part
);
4303 scm_real_part (SCM z
)
4308 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4311 if (!(SCM_INEXP (z
)))
4314 SCM_WTA_DISPATCH_1 (g_real_part
, z
, SCM_ARG1
, s_real_part
);
4317 SCM_GASSERT1 (SCM_INEXP (z
),
4318 g_real_part
, z
, SCM_ARG1
, s_real_part
);
4321 return scm_makdbl (SCM_REAL (z
), 0.0);
4328 SCM_GPROC (s_imag_part
, "imag-part", 1, 0, 0, scm_imag_part
, g_imag_part
);
4331 scm_imag_part (SCM z
)
4336 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4339 if (!(SCM_INEXP (z
)))
4342 SCM_WTA_DISPATCH_1 (g_imag_part
, z
, SCM_ARG1
, s_imag_part
);
4345 SCM_GASSERT1 (SCM_INEXP (z
),
4346 g_imag_part
, z
, SCM_ARG1
, s_imag_part
);
4349 return scm_makdbl (SCM_IMAG (z
), 0.0);
4355 SCM_GPROC (s_magnitude
, "magnitude", 1, 0, 0, scm_magnitude
, g_magnitude
);
4358 scm_magnitude (SCM z
)
4363 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4366 if (!(SCM_INEXP (z
)))
4369 SCM_WTA_DISPATCH_1 (g_magnitude
, z
, SCM_ARG1
, s_magnitude
);
4372 SCM_GASSERT1 (SCM_INEXP (z
),
4373 g_magnitude
, z
, SCM_ARG1
, s_magnitude
);
4377 double i
= SCM_IMAG (z
), r
= SCM_REAL (z
);
4378 return scm_makdbl (sqrt (i
* i
+ r
* r
), 0.0);
4380 return scm_makdbl (fabs (SCM_REALPART (z
)), 0.0);
4386 SCM_GPROC (s_angle
, "angle", 1, 0, 0, scm_angle
, g_angle
);
4394 x
= (z
>= SCM_INUM0
) ? 1.0 : -1.0;
4398 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4401 x
= (SCM_TYP16 (z
) == scm_tc16_bigpos
) ? 1.0 : -1.0;
4404 if (!(SCM_INEXP (z
)))
4407 SCM_WTA_DISPATCH_1 (g_angle
, z
, SCM_ARG1
, s_angle
);
4410 SCM_GASSERT1 (SCM_INEXP (z
), g_angle
, z
, SCM_ARG1
, s_angle
);
4414 x
= SCM_REALPART (z
);
4420 return scm_makdbl (atan2 (y
, x
), 0.0);
4424 SCM_DEFINE (scm_inexact_to_exact
, "inexact->exact", 1, 0, 0,
4427 #define FUNC_NAME s_scm_inexact_to_exact
4432 SCM_ASRTGO (SCM_NIMP (z
), badz
);
4435 #ifndef SCM_RECKLESS
4436 if (!(SCM_REALP (z
)))
4443 SCM_VALIDATE_REAL(1,z
);
4447 double u
= floor (SCM_REALPART (z
) + 0.5);
4448 if ((u
<= SCM_MOST_POSITIVE_FIXNUM
) && (-u
<= -SCM_MOST_NEGATIVE_FIXNUM
))
4450 /* Negation is a workaround for HP700 cc bug */
4451 SCM ans
= SCM_MAKINUM ((long) u
);
4452 if (SCM_INUM (ans
) == (long) u
)
4455 SCM_ASRTGO (isfinite (u
), badz
); /* problem? */
4456 return scm_dbl2big (u
);
4459 return SCM_MAKINUM ((long) floor (SCM_REALPART (z
) + 0.5));
4466 #else /* ~SCM_FLOATS */
4467 SCM_GPROC (s_trunc
, "truncate", 1, 0, 0, scm_trunc
, g_trunc
);
4472 SCM_GASSERT2 (SCM_INUMP (x
), g_trunc
, x
, y
, SCM_ARG1
, s_truncate
);
4478 #endif /* SCM_FLOATS */
4482 /* d must be integer */
4485 scm_dbl2big (double d
)
4491 double u
= (d
< 0) ? -d
: d
;
4492 while (0 != floor (u
))
4497 ans
= scm_mkbig (i
, d
< 0);
4498 digits
= SCM_BDIGITS (ans
);
4506 #ifndef SCM_RECKLESS
4508 scm_num_overflow ("dbl2big");
4519 scm_sizet i
= SCM_NUMDIGS (b
);
4520 SCM_BIGDIG
*digits
= SCM_BDIGITS (b
);
4522 ans
= digits
[i
] + SCM_BIGRAD
* ans
;
4523 if (scm_tc16_bigneg
== SCM_TYP16 (b
))
4532 scm_long2num (long sl
)
4534 if (!SCM_FIXABLE (sl
))
4537 return scm_long2big (sl
);
4540 return scm_makdbl ((double) sl
, 0.0);
4546 return SCM_MAKINUM (sl
);
4550 #ifdef HAVE_LONG_LONGS
4553 scm_long_long2num (long_long sl
)
4555 if (!SCM_FIXABLE (sl
))
4558 return scm_long_long2big (sl
);
4561 return scm_makdbl ((double) sl
, 0.0);
4567 return SCM_MAKINUM (sl
);
4574 scm_ulong2num (unsigned long sl
)
4576 if (!SCM_POSFIXABLE (sl
))
4579 return scm_ulong2big (sl
);
4582 return scm_makdbl ((double) sl
, 0.0);
4588 return SCM_MAKINUM (sl
);
4593 scm_num2long (SCM num
, char *pos
, const char *s_caller
)
4597 if (SCM_INUMP (num
))
4599 res
= SCM_INUM (num
);
4602 SCM_ASRTGO (SCM_NIMP (num
), wrong_type_arg
);
4604 if (SCM_REALP (num
))
4606 volatile double u
= SCM_REALPART (num
);
4617 unsigned long oldres
= 0;
4619 /* can't use res directly in case num is -2^31. */
4620 unsigned long pos_res
= 0;
4622 for (l
= SCM_NUMDIGS (num
); l
--;)
4624 pos_res
= SCM_BIGUP (pos_res
) + SCM_BDIGITS (num
)[l
];
4625 /* check for overflow. */
4626 if (pos_res
< oldres
)
4630 if (SCM_TYP16 (num
) == scm_tc16_bigpos
)
4646 scm_wrong_type_arg (s_caller
, (int) pos
, num
);
4648 scm_out_of_range (s_caller
, num
);
4653 #ifdef HAVE_LONG_LONGS
4656 scm_num2long_long (SCM num
, char *pos
, const char *s_caller
)
4660 if (SCM_INUMP (num
))
4662 res
= SCM_INUM (num
);
4665 SCM_ASRTGO (SCM_NIMP (num
), wrong_type_arg
);
4667 if (SCM_REALP (num
))
4669 double u
= SCM_REALPART (num
);
4672 if ((res
< 0 && u
> 0) || (res
> 0 && u
< 0)) /* check for overflow. */
4681 unsigned long long oldres
= 0;
4683 /* can't use res directly in case num is -2^63. */
4684 unsigned long long pos_res
= 0;
4686 for (l
= SCM_NUMDIGS (num
); l
--;)
4688 pos_res
= SCM_LONGLONGBIGUP (pos_res
) + SCM_BDIGITS (num
)[l
];
4689 /* check for overflow. */
4690 if (pos_res
< oldres
)
4694 if (SCM_TYP16 (num
) == scm_tc16_bigpos
)
4710 scm_wrong_type_arg (s_caller
, (int) pos
, num
);
4712 scm_out_of_range (s_caller
, num
);
4719 scm_num2ulong (SCM num
, char *pos
, const char *s_caller
)
4723 if (SCM_INUMP (num
))
4725 if (SCM_INUM (num
) < 0)
4727 res
= SCM_INUM (num
);
4730 SCM_ASRTGO (SCM_NIMP (num
), wrong_type_arg
);
4732 if (SCM_REALP (num
))
4734 double u
= SCM_REALPART (num
);
4745 unsigned long oldres
= 0;
4749 for (l
= SCM_NUMDIGS (num
); l
--;)
4751 res
= SCM_BIGUP (res
) + SCM_BDIGITS (num
)[l
];
4760 scm_wrong_type_arg (s_caller
, (int) pos
, num
);
4762 scm_out_of_range (s_caller
, num
);
4769 add1 (double f
, double *fsum
)
4781 scm_add_feature("complex");
4783 scm_add_feature("inexact");
4785 SCM_NEWSMOB(scm_flo0
,scm_tc_flo
,NULL
);
4787 SCM_NEWSMOB(scm_flo0
,scm_tc_dblr
,scm_must_malloc (1L * sizeof (double), "real"));
4788 SCM_REAL (scm_flo0
) = 0.0;
4791 scm_dblprec
= (DBL_DIG
> 20) ? 20 : DBL_DIG
;
4793 { /* determine floating point precision */
4795 double fsum
= 1.0 + f
;
4799 if (++scm_dblprec
> 20)
4803 scm_dblprec
= scm_dblprec
- 1;
4805 #endif /* DBL_DIG */
4807 #include "numbers.x"