-/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc.
+/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002 Free Software Foundation, Inc.
*
* Portions Copyright 1990, 1991, 1992, 1993 by AT&T Bell Laboratories
* and Bellcore. See scm_divide.
#include <math.h>
#include <ctype.h>
+#include <string.h>
#include "libguile/_scm.h"
#include "libguile/feature.h"
#include "libguile/ports.h"
static SCM scm_divbigint (SCM x, long z, int sgn, int mode);
-#define SCM_SWAP(x,y) do { SCM __t = x; x = y; y = __t; } while (0)
+#define SCM_SWAP(x, y) do { SCM __t = x; x = y; y = __t; } while (0)
/* FLOBUFLEN is the maximum number of characters neccessary for the
return SCM_MAKINUM (-1);
} else if (!SCM_NUMBERP (n1)) {
SCM_WRONG_TYPE_ARG (SCM_ARG1, n1);
-#ifndef SCM_RECKLESS
} else if (SCM_NUMBERP (n1)) {
return n1;
} else {
SCM_WRONG_TYPE_ARG (SCM_ARG1, n1);
-#else
- } else {
- return n1;
-#endif
}
}
if (SCM_UNBNDP (n2)) {
if (SCM_UNBNDP (n1)) {
return SCM_INUM0;
-#ifndef SCM_RECKLESS
} else if (SCM_NUMBERP (n1)) {
return n1;
} else {
SCM_WRONG_TYPE_ARG (SCM_ARG1, n1);
-#else
- } else {
- return n1;
-#endif
}
}
if (SCM_UNBNDP (n2)) {
if (SCM_UNBNDP (n1)) {
return SCM_INUM0;
-#ifndef SCM_RECKLESS
} else if (SCM_NUMBERP (n1)) {
return n1;
} else {
SCM_WRONG_TYPE_ARG (SCM_ARG1, n1);
-#else
- } else {
- return n1;
-#endif
}
}
SCM acc = SCM_MAKINUM (1L);
int i2;
#ifdef SCM_BIGDIG
+ /* 0^0 == 1 according to R5RS */
if (SCM_EQ_P (n, SCM_INUM0) || SCM_EQ_P (n, acc))
- return n;
+ return SCM_FALSEP (scm_zero_p(k)) ? n : acc;
else if (SCM_EQ_P (n, SCM_MAKINUM (-1L)))
return SCM_FALSEP (scm_even_p (k)) ? n : acc;
#endif
SCM_WRONG_TYPE_ARG (2, k);
}
else
- SCM_VALIDATE_ULONG_COPY (2,k,i2);
+ SCM_VALIDATE_ULONG_COPY (2, k, i2);
if (i2 < 0)
{
i2 = -i2;
#define FUNC_NAME s_scm_bit_extract
{
unsigned long int istart, iend;
- SCM_VALIDATE_INUM_MIN_COPY (2,start,0,istart);
+ SCM_VALIDATE_INUM_MIN_COPY (2, start,0, istart);
SCM_VALIDATE_INUM_MIN_COPY (3, end, 0, iend);
SCM_ASSERT_RANGE (3, end, (iend >= istart));
int exp = 0;
if (f == 0.0)
- goto zero; /*{a[0]='0'; a[1]='.'; a[2]='0'; return 3;} */
+ {
+#ifdef HAVE_COPYSIGN
+ double sgn = copysign (1.0, f);
+
+ if (sgn < 0.0)
+ a[ch++] = '-';
+#endif
+
+ goto zero; /*{a[0]='0'; a[1]='.'; a[2]='0'; return 3;} */
+ }
if (xisinf (f))
{
SCM_BIGDIG radpow = 1, radmod = 0;
SCM ss = scm_allocate_string (j);
char *s = SCM_STRING_CHARS (ss), c;
+
+ if (i == 0)
+ {
+ return scm_makfrom0str ("0");
+ }
+
while ((long) radpow * radix < SCM_BIGRAD)
{
radpow *= radix;
unsigned int radix, enum t_exactness *p_exactness)
{
unsigned int idx = *p_idx;
+ SCM result;
if (idx == len)
return SCM_BOOL_F;
else if (!isdigit (mem[idx + 1]))
return SCM_BOOL_F;
else
- return mem2decimal_from_point (SCM_MAKINUM (0), mem, len,
- p_idx, p_exactness);
+ result = mem2decimal_from_point (SCM_MAKINUM (0), mem, len,
+ p_idx, p_exactness);
}
else
{
enum t_exactness x = EXACT;
SCM uinteger;
- SCM result;
uinteger = mem2uinteger (mem, len, &idx, radix, &x);
if (SCM_FALSEP (uinteger))
*p_idx = idx;
if (x == INEXACT)
*p_exactness = x;
-
- return result;
}
+
+ /* When returning an inexact zero, make sure it is represented as a
+ floating point value so that we can change its sign.
+ */
+ if (SCM_EQ_P (result, SCM_MAKINUM(0)) && *p_exactness == INEXACT)
+ result = scm_make_real (0.0);
+
+ return result;
}
}
else
{
- if (sign == -1)
+ if (sign == -1 && SCM_FALSEP (scm_nan_p (ureal)))
ureal = scm_difference (ureal, SCM_UNDEFINED);
if (idx == len)
if (idx != len)
return SCM_BOOL_F;
- if (sign == -1)
+ if (sign == -1 && SCM_FALSEP (scm_nan_p (ureal)))
angle = scm_difference (angle, SCM_UNDEFINED);
result = scm_make_polar (ureal, angle);
if (SCM_FALSEP (imag))
imag = SCM_MAKINUM (sign);
- else if (sign == -1)
+ else if (sign == -1 && SCM_FALSEP (scm_nan_p (ureal)))
imag = scm_difference (imag, SCM_UNDEFINED);
if (idx == len)
SCM answer;
int base;
SCM_VALIDATE_STRING (1, string);
- SCM_VALIDATE_INUM_MIN_DEF_COPY (2,radix,2,10,base);
+ SCM_VALIDATE_INUM_MIN_DEF_COPY (2, radix,2,10, base);
answer = scm_i_mem2number (SCM_STRING_CHARS (string),
SCM_STRING_LENGTH (string),
base);
SCM
scm_make_real (double x)
{
- SCM z;
- z = scm_double_cell (scm_tc16_real, 0, 0, 0);
+ SCM z = scm_double_cell (scm_tc16_real, 0, 0, 0);
+
SCM_REAL_VALUE (z) = x;
return z;
}
SCM_WTA_DISPATCH_2 (g_leq_p, x, y, SCM_ARG1, FUNC_NAME);
else if (!SCM_NUMBERP (y))
SCM_WTA_DISPATCH_2 (g_leq_p, x, y, SCM_ARG2, FUNC_NAME);
+ else if (SCM_NFALSEP (scm_nan_p (x)) || SCM_NFALSEP (scm_nan_p (y)))
+ return SCM_BOOL_F;
else
return SCM_BOOL_NOT (scm_less_p (y, x));
}
SCM_WTA_DISPATCH_2 (g_geq_p, x, y, SCM_ARG1, FUNC_NAME);
else if (!SCM_NUMBERP (y))
SCM_WTA_DISPATCH_2 (g_geq_p, x, y, SCM_ARG2, FUNC_NAME);
+ else if (SCM_NFALSEP (scm_nan_p (x)) || SCM_NFALSEP (scm_nan_p (y)))
+ return SCM_BOOL_F;
else
- return SCM_BOOL_NOT (scm_less_p (x, y));
+ return SCM_BOOL_NOT (scm_less_p (x, y));
}
#undef FUNC_NAME
if (SCM_FIXABLE (lu)) {
return SCM_MAKINUM (lu);
#ifdef SCM_BIGDIG
- } else if (isfinite (u)) {
+ } else if (isfinite (u) && !xisnan (u)) {
return scm_i_dbl2big (u);
#endif
} else {
u -= c;
digits[i] = c;
}
-#ifndef SCM_RECKLESS
if (u != 0)
scm_num_overflow ("dbl2big");
-#endif
return ans;
}