1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-02 13:00:26 +02:00
Commit graph

144 commits

Author SHA1 Message Date
Mark H Weaver
aa13da5189 Fix atan procedure when applied to complex numbers.
Fixes a regression introduced in commit
ad79736c68.

* libguile/numbers.c (scm_atan): Fix the complex case.
* test-suite/tests/numbers.test ("atan"): Add test.
2016-05-22 19:29:38 +02:00
Mark H Weaver
7af706e36e Fix 'exact-integer?' comment in numbers.test.
* test-suite/tests/numbers.test: Fix 'exact-integer?' comment.
2014-01-12 07:47:00 -05:00
Mark H Weaver
900a897cd3 Implement 'exact-integer?' and 'scm_is_exact_integer'.
* libguile/numbers.c (scm_exact_integer_p, scm_is_exact_integer):
  New procedures.
  (scm_integer_p): Improve docstring.

* libguile/numbers.h (scm_exact_integer_p, scm_is_exact_integer):
  New prototypes.

* doc/ref/api-data.texi (Integers): Add docs.

* test-suite/tests/numbers.test ("exact-integer?"): Add tests.
2014-01-08 21:42:16 -05:00
Mark H Weaver
d360671c1c Fix edge case in 'ash'.
* libguile/numbers.c (left_shift_exact_integer): Fix edge case where
  N is -1 and count is SCM_I_FIXNUM_BIT-1 to return the most negative
  fixnum.  Previously this result was returned as a bignum.

* test-suite/tests/numbers.test (ash): Add tests.
2013-10-03 19:08:24 -04:00
Mark H Weaver
1ea0803e9e Revert "Fix edge case in 'ash'."
This reverts commit 8df68898b9.
2013-10-03 19:08:23 -04:00
Mark H Weaver
8df68898b9 Fix edge case in 'ash'.
* libguile/numbers.c (scm_ash): Fix (ash -1 SCM_I_FIXNUM_BIT-1) to
  return a fixnum instead of a bignum.

* test-suite/tests/numbers.test (ash): Add tests.
2013-10-03 14:25:51 -04:00
Mark H Weaver
fa102e73c3 Fix numerator and denominator handling of signed zeroes and infinities.
* libguile/numbers.c (scm_numerator, scm_denominator): Handle signed
  zeroes and infinities in accordance with the corresponding R6RS flonum
  procedures.

* module/rnrs/arithmetic/flonums.scm (flnumerator, fldenominator):
  Remove special handling of infinities.

* test-suite/tests/numbers.test (numerator, denominator): Add tests.
  Convert existing tests to use 'pass-if-equal'.

* test-suite/tests/r6rs-arithmetic-flonums.test (flnumerator): Fix
  broken test of (flnumerator -0.0).
2013-08-09 06:09:56 -04:00
Mark H Weaver
620c13e8fc Rewrite 'rationalize' to fix bugs and improve efficiency.
Fixes <http://bugs.gnu.org/14905>.
Reported by Göran Weinholt <goran@weinholt.se>.

* libguile/numbers.c (scm_rationalize): Rewrite.  Previously an
  incorrect algorithm was used which failed in many cases.

* test-suite/tests/numbers.test (rationalize): Add tests.
2013-07-21 06:44:54 -04:00
Mark H Weaver
3bbca1f723 gcd and lcm support inexact integer arguments.
Fixes <http://bugs.gnu.org/14870>.
Reported by Göran Weinholt <goran@weinholt.se>.

* libguile/numbers.c (scm_gcd, scm_lcm): Support inexact integers.

* test-suite/tests/numbers.test (gcd, lcm): Add tests.
2013-07-16 06:41:07 -04:00
Mark H Weaver
b4c55c9cce min and max: NaNs beat infinities, per R6RS errata.
Fixes <http://bugs.gnu.org/14865>.
Reported by Göran Weinholt <goran@weinholt.se>.

* libguile/numbers.c (scm_min, scm_max): NaNs beat infinities, as per
  the R6RS errata.

* test-suite/tests/numbers.test (min, max): Update tests.
2013-07-16 05:18:15 -04:00
Mark H Weaver
284859c2f9 numbers.test: Fix inum/flonum comparison test on 32-bit machines.
* test-suite/tests/numbers.test (<): Fix inum/flonum test.
2013-07-16 01:46:05 -04:00
Mark H Weaver
95ed221785 Avoid lossy conversion from inum to double in numerical comparisons.
* libguile/numbers.c (scm_less_p): Avoid converting inums to doubles.

* test-suite/tests/numbers.test (<): Add tests.
2013-07-16 00:26:11 -04:00
Mark H Weaver
ba0e46ea1b numbers.test: Avoid inexact arithmetic in computation of fixnum-bit.
* test-suite/tests/numbers.test (fixnum-bit): Rewrite to avoid
  inexact arithmetic.
2013-07-16 00:22:10 -04:00
Mark H Weaver
0132928891 Fix bugs in numerical equality predicate.
* libguile/numbers.c (scm_num_eq_p): Fix bug comparing fractions to
  infinities (reported by Göran Weinholt <goran@weinholt.se>).  Fix
  erroneous comment describing the logic behind inum/flonum comparison.
  Use similar logic for inum/complex comparison to avoid rounding
  errors.  Make minor indentation fixes and simplifications.

* test-suite/tests/numbers.test (=): Add tests.
2013-07-16 00:18:40 -04:00
Mark H Weaver
4cc2e41cf7 Fix rounding in scm_i_divide2double for negative arguments.
* libguile/numbers.c (INUM_LOSSLESSLY_CONVERTIBLE_TO_DOUBLE):
  New macro.
  (scm_i_divide2double): Use INUM_LOSSLESSLY_CONVERTIBLE_TO_DOUBLE to
  determine if our fast path is safe.  Previously, negative arguments
  were not checked properly.

* test-suite/tests/numbers.test (exact->inexact): Add tests.
2013-07-16 00:00:23 -04:00
Mark H Weaver
f480a98e9a Add 2012 and 2013 to copyright notice on numbers.test.
* test-suite/tests/numbers.test: Add 2012 and 2013 to copyright notice.
  It was modified both of those years.
2013-04-10 20:07:22 -04:00
Mark H Weaver
ddb7174236 Improve sqrt handling of large integers and large and small rationals.
* libguile/numbers.c (exact_integer_is_perfect_square,
  exact_integer_floor_square_root): New static functions.

  (scm_sqrt): Use SCM_LIKELY.  Add 'scm_t_inum' variable in inum case to
  reduce the number of uses of SCM_I_INUM.  Rename 'mpz_t' variable.
  Remove unneeded sign check.  Handle bignums too large to fit in a
  double.  Handle fractions too large or too small to fit in a
  normalized double.

* test-suite/tests/numbers.test ("sqrt"): Add tests.
2013-03-20 06:27:39 -04:00
Mark H Weaver
4400266478 Sqrt returns exact results when possible.
* libguile/numbers.c (scm_sqrt): Handle exact integers and rationals in
  such a way that exact results are returned whenever possible.

* test-suite/tests/numbers.test ("sqrt"): Add tests.
2013-03-20 00:13:43 -04:00
Mark H Weaver
8150dfa1f2 Use scientific notation only if there are enough trailing zeroes.
* libguile/numbers.c (idbl2str): Print large numbers in scientific
  notation only if the exponent is >= 7 and the least significant
  non-zero digit has value >= radix^4.

* test-suite/tests/numbers.test ("number->string"): Add tests.
2013-03-19 03:38:15 -04:00
Mark H Weaver
1ea37620c2 Reimplement idbl2str number printer.
Fixes <http://bugs.gnu.org/13757>.

* libguile/numbers.c (idbl2str): Reimplement.
  (mem2decimal_from_point): Accept negative exponents larger than
  SCM_MAXEXP that produce subnormals.
  (SCM_MAX_DBL_PREC): Removed preprocessor macro.
  (scm_dblprec, fx_per_radix): Removed static variables.
  (init_dblprec, init_fx_radix): Removed static functions.
  (scm_init_numbers): Remove initialization code for 'scm_dblprec'
  and 'fx_per_radix'.

* test-suite/tests/numbers.test ("number->string"): Restore tests that
  previously failed.  Remove comments about problems in the number
  printer that are now fixed.
2013-03-17 18:52:31 -04:00
Mark H Weaver
9823778490 Improve inexact division of exact integers.
* libguile/numbers.c (scm_i_divide2double): New function.
  (scm_i_divide2double_lo2b): New variable.
  (scm_i_fraction2double, log_of_fraction): Use 'scm_i_divide2double'.
  (do_divide): Removed.  Its code is now in 'scm_divide'.
  (scm_divide2real): Removed.  Superceded by 'scm_i_divide2double'.
  (scm_divide): Inherit code from 'do_divide', but without support for
  forcing a 'double' result (that functionality is now implemented by
  'scm_i_divide2double').  Add FIXME comments in cases where divisions
  might not be as precise as they should be.
  (scm_init_numbers): Initialize 'scm_i_divide2double_lo2b'.

* test-suite/tests/numbers.test (dbl-epsilon-exact, dbl-max-exp): New
  variables.
  ("exact->inexact"): Add tests.
  ("inexact->exact"): Add test for largest finite inexact.
2013-03-17 16:37:55 -04:00
Mark H Weaver
24475b860b Reimplement 'inexact->exact' to avoid mpq functions.
* libguile/numbers.c (scm_inexact_to_exact): Implement conversion of a
  double to an exact rational without using the mpq functions.

* test-suite/tests/numbers.test (dbl-mant-dig): Simplify initializer.
  (dbl-epsilon, dbl-min-exp): New variables.
  ("inexact->exact"): Add tests.  Fix broken "2.0**i to exact and back"
  test, and change it to "2.0**i to exact", to avoid use of
  'exact->inexact'.
2013-03-12 15:39:34 -04:00
Mark H Weaver
1eb6a33a30 Simplify and improve scm_i_big2dbl, and add scm_i_big2dbl_2exp
* libguile/numbers.c (scm_i_big2dbl_2exp): New static function.
  (scm_i_big2dbl): Reimplement in terms of 'scm_i_big2dbl_2exp',
  with proper rounding.

* test-suite/tests/numbers.test ("exact->inexact"): Add tests.
2013-03-12 15:39:25 -04:00
Mark H Weaver
e08a12b535 Add 'round-ash', a rounding arithmetic shift operator
* libguile/numbers.c (left_shift_exact_integer,
  floor_right_shift_exact_integer, round_right_shift_exact_integer): New
  static functions.

  (scm_round_ash): New procedure.

  (scm_ash): Reimplement in terms of 'left_shift_exact_integer' and
  'floor_right_shift_exact_integer'.

* libguile/numbers.h: Add prototype for scm_round_ash.  Rename the
  second argument of 'scm_ash' from 'cnt' to 'count'.

* test-suite/tests/numbers.test (round-ash, ash): Add new unified
  testing framework for 'ash' and 'round-ash'.  Previously, the tests
  for 'ash' were not very comprehensive; for example, they did not
  include a single test where the number to be shifted was a bignum.

* doc/ref/api-data.texi (Bitwise Operations): Add documentation for
  'round-ash'.  Improve documentation for `ash'.
2013-03-12 15:39:20 -04:00
Mark H Weaver
a285b18ca8 Optimize and simplify fractions code.
* libguile/numbers.c (scm_exact_integer_quotient,
  scm_i_make_ratio_already_reduced): New static functions.

  (scm_i_make_ratio): Rewrite in terms of
  'scm_i_make_ratio_already_reduced'.

  (scm_integer_expt): Optimize fraction case.

  (scm_abs, scm_magnitude, scm_difference, do_divide): Use
  'scm_i_make_ratio_already_reduced'.

* test-suite/tests/numbers.test (expt, integer-expt): Add tests.
2013-03-12 15:39:16 -04:00
Mark H Weaver
929d11b2c1 Improve standards conformance of string->number.
Fixes <http://bugs.gnu.org/11887>.

* libguile/numbers.c (mem2ureal): New argument 'allow_inf_or_nan'.
  Accept infinities and NaNs only if 'allow_inf_or_nan' is true and "#e"
  is not present.  Check for "inf.0" or "nan." case-insensitively.  Do
  not accept rationals with zero divisors.

  (mem2complex): Pass new 'allow_inf_or_nan' argument to 'mem2ureal',
  which is set if and only if a explicit sign was present.

* test-suite/tests/numbers.test ("string->number"): Add tests.
2013-03-07 15:37:15 -05:00
Mark H Weaver
2355f01709 Avoid signed integer overflow in scm_product
* libguile/numbers.c (scm_product): Avoid signed integer overflow, which
  modern C compilers are allowed to assume will never happen, thus
  allowing them to optimize out our overflow checks.

* test-suite/tests/numbers.test (*): Add tests.
2012-12-07 12:02:07 -05:00
Mark H Weaver
fb210d8d16 Test number-theoretic division by -0.0.
* test-suite/tests/numbers.test ("Number-theoretic division"): Fix typo
  so that we actually test for division by -0.0.
2012-10-30 02:23:07 -04:00
Mark H Weaver
639fd0a442 Revert "Add tests for 'exp' and 'expt' that should produce complex NaNs"
This reverts commit cc26b9de1d.
2012-08-07 18:14:32 -04:00
Mark H Weaver
cc26b9de1d Add tests for 'exp' and 'expt' that should produce complex NaNs
* test-suite/tests/numbers.test (exp, expt): Add tests that should
  produce complex NaNs, but apparently don't on all systems.
2012-07-28 13:07:38 -04:00
Mark H Weaver
10a97755d4 Angle of -0.0 is pi, not zero
* libguile/numbers.c (scm_angle): Check the sign of an inexact real
  zero, to ensure that (angle -0.0) => pi and (angle 0.0) => 0.0.

* test-suite/tests/numbers.test (angle): Add tests, and increase
  precision of tests where the angle should be pi.
2012-07-28 02:45:05 -04:00
Mark H Weaver
882c89636a Fix the R6RS exact-integer-sqrt and import into core guile
* libguile/numbers.c (scm_exact_integer_sqrt): New C procedure to
  compute exact integer square root and remainder.
  (scm_i_exact_integer_sqrt): New Scheme procedure `exact-integer-sqrt'
  from the R6RS, imported into core guile.

* libguile/numbers.h: Add prototypes.

* module/rnrs/base.scm: Remove broken stub implementation, which would
  fail badly when applied to large integers.

* doc/ref/api-data.texi: Add documentation.

* doc/ref/r6rs.texi: Change documentation for `exact-integer-sqrt' to a
  stub that xrefs the core docs, as is done for other operations
  available in core.

* test-suite/tests/numbers.test: Add tests.

* NEWS: Add news entries.
2011-04-09 16:11:49 -04:00
Mark H Weaver
6ebecdeb7d Fix parsing of exact numbers with negative exponents
* libguile/numbers.c (mem2decimal_from_point): Use scm_divide instead of
  scm_divide2real when applying a negative exponent, to preserve
  exactness in case the "#e" forced exactness specifier is present.
  This fixes a bug where numeric literals such as "#e1e-5" yielded
  incorrect fractions.
2011-04-06 18:24:40 -04:00
Mark H Weaver
495a39c40f Quotient, remainder and modulo accept inexact integers
* libguile/numbers.c (scm_quotient, scm_remainder, scm_modulo): Accept
  inexact integers as well as exact ones, as required by the R5RS.

* test-suite/tests/numbers.test (quotient, remainder, modulo): Add tests.
2011-03-08 18:18:31 -05:00
Mark H Weaver
a5f6b751be Improvements to log' and log10'
* libguile/numbers.c (log_of_shifted_double, log_of_exact_integer,
  log_of_exact_integer_with_size, log_of_fraction): New internal static
  functions used by scm_log and scm_log10.

  (scm_log, scm_log10): Robustly handle large integers, large and small
  fractions, and fractions close to 1.  Previously, computing logarithms
  of fractions close to 1 yielded grossly inaccurate results, and the
  other cases yielded infinities even though the answer could easily fit
  in a double.  (log -0.0) now returns -inf.0+<PI>i, where previously it
  returned -inf.0.  (log 0) now throws a numerical overflow exception,
  where previously it returned -inf.0.  (log 0.0) still returns -inf.0.
  Analogous changes made to `log10'.

* test-suite/tests/numbers.test (log, log10): Add tests.

Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2011-02-16 00:40:35 +01:00
Mark H Weaver
c05696aa94 Fix comment above number-theoretic division tests
* test-suite/tests/numbers.test: Fix comment.

Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2011-02-16 00:40:11 +01:00
Mark H Weaver
8b56bcec44 Optimize truncate, round, floor, and ceiling
* libguile/numbers.c (scm_c_truncate): Use ceil (x) instead of
  -floor (-x).

  (scm_truncate_number): Implement directly instead of by checking the
  sign and using scm_floor or scm_ceiling.  Use scm_truncate_quotient
  for fractions.  Make extensible, so that new number types implemented
  in GOOPS will be able to do the job more efficiently, since it is
  often easier to implement truncate than floor or ceiling.

  (scm_round_number): Optimize fractions case by using
  scm_round_quotient.  Make extensible, so that new number types
  implemented in GOOPS will be able to do the job efficiently.

  (scm_floor, scm_ceiling): Optimize fractions case by using
  scm_floor_quotient and scm_ceiling_quotient, respectively.

* test-suite/tests/numbers.test: Add test cases.
2011-02-14 20:31:14 +01:00
Mark H Weaver
8f9da3406b Add four new sets of fast quotient and remainder operators
* libguile/numbers.c (scm_floor_divide, scm_floor_quotient,
  scm_floor_remainder, scm_ceiling_divide, scm_ceiling_quotient,
  scm_ceiling_remainder, scm_truncate_divide, scm_truncate_quotient,
  scm_truncate_remainder, scm_round_divide, scm_round_quotient,
  scm_round_remainder): New extensible procedures `floor/',
  `floor-quotient', `floor-remainder', `ceiling/', `ceiling-quotient',
  `ceiling-remainder', `truncate/', `truncate-quotient',
  `truncate-remainder', `round/', `round-quotient', and
  `round-remainder'.

* libguile/numbers.h: Add function prototypes.

* test-suite/tests/numbers.test: Add tests.

* doc/ref/api-data.texi (Arithmetic): Add documentation.

* NEWS: Add NEWS entry.
2011-02-14 20:30:53 +01:00
Mark H Weaver
4a46bc2a5f Fixes and improvements to number-theoretic division operators
* libguile/numbers.c (scm_euclidean_quotient, scm_euclidean_divide,
  scm_centered_quotient, scm_centered_divide): Fix bug in inum/inum
  case, where (quotient most-negative-fixnum -1) would not be converted
  to a bignum.

  (scm_euclidean_quotient): Be more anal-retentive about calling
  scm_remember_upto_here_1 after mpz_sgn, (even though mpz_sgn is
  documented as being implemented as a macro and certainly won't
  do any allocation).  It's better to be safe than sorry here.

  (scm_euclidean_quotient, scm_centered_quotient): In the bignum/inum
  case, check if the divisor is 1, since this will allow us to avoid
  allocating a new bignum.

  (scm_euclidean_divide, scm_centered_quotient, scm_centered_divide):
  When computing the intermediate truncated quotient (xx / yy) and
  remainder, use (xx % yy) instead of (xx - qq * yy), on the theory that
  the compiler is more likely to handle this case intelligently and
  maybe combine the operations.

  (scm_euclidean_divide): In the bignum/inum case, we know that the
  remainder will fit in an fixnum, so don't bother allocating a bignum
  for it.

  (scm_euclidean_quotient, scm_euclidean_remainder,
  scm_euclidean_divide, scm_centered_quotient, scm_centered_remainder,
  scm_centered_divide): Minor stylistic changes.

* test-suite/tests/numbers.test: Rework testing framework for
  number-theoretic division operators to be more efficient and
  comprehensive in its testing of code paths and problem cases.
2011-02-12 13:00:43 +01:00
Mark H Weaver
9d427b2cc3 Improved exactness handling for complex number parsing
When parsing non-real complex numbers, apply exactness specifiers on
per-component basis, as is done in PLT Scheme.  For complex numbers
written in rectangular form, exactness specifiers are applied to the
real and imaginary parts before calling scm_make_rectangular.  For
complex numbers written in polar form, exactness specifiers are applied
to the magnitude and angle before calling scm_make_polar.

There are two kinds of exactness specifiers: forced and implicit.  A
forced exactness specifier is a "#e" or "#i" prefix at the beginning of
the entire number, and applies to both components of a complex number.
"#e" causes each component to be made exact, and "#i" causes each
component to be made inexact.  If no forced exactness specifier is
present, then the exactness of each component is determined
independently by the presence or absence of a decimal point or hash mark
within that component.  If a decimal point or hash mark is present, the
component is made inexact, otherwise it is made exact.

After the exactness specifiers have been applied to each component, they
are passed to either scm_make_rectangular or scm_make_polar to produce
the final result.  Note that this will result in a real number if the
imaginary part, magnitude, or angle is an exact 0.

Previously, both forced and implicit exactness specifiers applied to
the number as a whole _after_ calling scm_make_rectangular or
scm_make_polar.

For example, (string->number "#i5.0+0i") now does the equivalent of:

  (make-rectangular (exact->inexact 5.0) (exact->inexact 0))

which yields 5.0+0.0i.  Previously it did the equivalent of:

  (exact->inexact (make-rectangular 5.0 0))

which yielded 5.0.

* libguile/numbers.c (mem2ureal): Receive a forced exactness specifier
  (forced_x), create and maintain our own implicit exactness specifier
  flag local to this component (implicit_x), and apply these exactness
  specifiers within this function.  Previously, we received a pointer to
  an implicit exactness specifier flag from above, and the exactness
  specifiers were applied from within scm_i_string_length.

  (mem2complex): Receive a forced exactness specifier parameter and pass
  it down to mem2ureal.  Previously, we passed down a pointer to an
  implicit exactness specifier flag instead.

  (scm_i_string_to_number): No longer create an implicit exactness
  specifier flag here, and do not apply exactness specifiers here.  All
  we do here now regarding exactness is to parse the "#e" or "#i" prefix
  (if any) and pass this information down to mem2ureal via mem2complex
  in the form of an explicit exactness specifier (forced_x).

  (scm_c_make_polar): If the cosine and sine of the angle are both NaNs
  and the magnitude is zero, return 0.0+0.0i instead of +nan.0+nan.0i.
  This case happens when the angle is not finite.

* test-suite/tests/numbers.test (string->number): Move the test cases
  for non-real complex numbers into a separate table in which the
  expected real and imaginary parts are separate entries.  Add several
  new test cases.
2011-02-03 10:50:24 +01:00
Mark H Weaver
c721848287 Support non-real complex numbers with inexact zero imaginary part
Add the ability to represent non-real complex numbers whose imaginary
part is an _inexact_ zero (0.0 or -0.0), per R6RS.  Previously, such
numbers were immediately changed into inexact reals.

* libguile/numbers.c: Remove from the list of `General assumptions' in
  numbers.c that objects satisfying SCM_COMPLEXP() have a non-zero
  complex component.  This is no longer true.  Also add a warning
  about another unrelated assumption that is not entirely correct
  (that floor(r) == r implies that mpz_set_d will DTRT; it won't
  if r is infinite).

  (icmplx2str): Always print the imaginary part, even if it is zero.
  Also handle a negative zero imaginary part more gracefully.  It
  now prints 0.0-0.0i, where previously it would print 0.0+-0.0i.

  (mem2ureal): Replace scm_from_double (0.0) with flo0.

  (scm_c_make_rectangular): Always create non-real complex numbers.
  Previously it would create inexact reals if the specified imaginary
  part was zero.

  (scm_make_rectangular): If the imaginary part is an _exact_ 0, return
  the real part unchanged (possibly exact), otherwise return a non-real
  complex number (possibly with an inexact zero imaginary part).
  Previously, it would return an inexact real number whenever the
  imaginary part was any kind of zero.

  (scm_make_polar): If the magnitude is an exact 0, return an exact 0.
  If the angle is an exact 0, return the magnitude unchanged (possibly
  exact).  Otherwise return a non-real complex number (possibly with an
  inexact zero imaginary part).  Previously, it would return a real
  number whenever the imaginary part was any kind of zero.

  (scm_imag_part): Return an exact 0 if applied to a real number.
  Previously it would return an inexact zero if applied to an inexact
  real number.

  (scm_inexact_to_exact): Accept complex numbers with inexact zero
  imaginary part.  In that case, simply use the real part and ignore the
  imaginary part.  Essentially we coerce the inexact zero imaginary part
  to an exact 0.

* test-suite/tests/numbers.test: Add many test cases, and modify
  existing tests as needed to reflect these changes.  Also add a new
  internal predicate: `almost-real-nan?' which tests for a non-real
  complex number with zero imaginary part whose real part is a NaN.

* doc/ref/api-data.texi (Complex Numbers): Update description of complex
  numbers to reflect these changes: non-real complex numbers in Guile
  need not have non-zero imaginary part.  Also, each part of a complex
  number may be any inexact real, not just rationals as was previously
  stated.  Explicitly mention that each part may be an infinity, a NaN,
  or a signed zero.

  (Complex Number Operations): Change the formal parameter names of
  `make-polar' from `x' and `y' to `mag' and `ang'.

* NEWS: Add news entries.
2011-02-02 21:34:01 +01:00
Mark H Weaver
9b9ef10cf0 Improve handling of signed zeroes
* libguile/numbers.c (scm_abs): (abs -0.0) now returns 0.0.  Previously
  it returned -0.0.  Also move the REALP case above the BIGP case,
  and consider it SCM_LIKELY to be REALP if not INUMP.
  (scm_difference): (- 0 0.0) now returns -0.0.  Previously it returned
  0.0.  Also make sure that (- 0 0.0+0.0i) will return -0.0-0.0i.

* test-suite/tests/numbers.test (abs, -): Add test cases, and change
  some tests to use `eqv?' instead of `=', in order to test exactness
  and distinguish signed zeroes.
2011-02-02 21:28:18 +01:00
Mark H Weaver
8deddc948d Trigonometric functions return exact numbers in some cases
* libguile/numbers.c (scm_sin, scm_cos, scm_tan, scm_asin, scm_acos,
  scm_atan, scm_sinh, scm_cosh, scm_tanh, scm_sys_asinh, scm_sys_acosh,
  scm_sys_atanh): Return an exact result in some cases.

* test-suite/tests/numbers.test: Add test cases.

* NEWS: Add NEWS entry
2011-02-02 21:26:35 +01:00
Mark H Weaver
2e2743113a Fix min' and max' handling of NaNs, infinities, and signed zeroes
* libguile/numbers.c (scm_min, scm_max): Properly order the real
  infinities and NaNs, per R6RS, and also take care to handle signed
  zeroes properly.  Note that this ordering is different than that of
  `<', `>', `<=', and `>=', which return #f if any argument is a real
  NaN, and consider the real zeroes to be equal.  The relevant real
  infinity (-inf.0 for min, +inf.0 for max) beats everything, including
  NaNs, and NaNs beat everything else.  Previously these were handled
  improperly in some cases, e.g.:
  (min 1/2 +nan.0) now returns +nan.0 (previously returned 0.5),
  (max 1/2 +nan.0) now returns +nan.0 (previously returned 0.5),
  (min -inf.0 +nan.0) now returns -inf.0 (previously returned +nan.0),
  (max +inf.0 +nan.0) now returns +inf.0 (previously returned +nan.0),
  (min -0.0  0.0) now returns -0.0 (previously returned  0.0),
  (max  0.0 -0.0) now returns  0.0 (previously returned -0.0),
  (max  0   -0.0) now returns  0.0 (previously returned -0.0),
  (max -0.0  0  ) now returns  0.0 (previously returned -0.0).

* test-suite/tests/numbers.test (min, max): Add many more test cases
  relating to NaNs, infinities, and signed zeroes.  Change most existing
  test cases to use `eqv?' instead of `=', in order to check exactness.
2011-02-02 21:21:21 +01:00
Mark H Weaver
5e7918077a Handle products with exact 0 differently
* libguile/numbers.c (scm_product): Handle exact 0 differently.  A
  product containing an exact 0 now returns an exact 0 if and only if
  the other arguments are all exact.  An inexact zero is returned if and
  only if the other arguments are all finite but not all exact.  If an
  infinite or NaN value is present, a NaN value is returned.
  Previously, any product containing an exact 0 yielded an exact 0,
  regardless of the other arguments.

  A note on the rationale for (* 0 0.0) returning 0.0 and not exact 0:
  The exactness propagation rules allow us to return an exact result in
  the presence of inexact arguments only if the values of the inexact
  arguments do not affect the result.  In this case, the value of the
  inexact argument _does_ affect the result, because an infinite or NaN
  value causes the result to be a NaN.

  A note on the rationale for (* 0 +inf.0) being a NaN and not exact 0:
  The R6RS requires that (/ 0 0.0) return a NaN value, and that (/ 0.0)
  return +inf.0.  We would like (/ x y) to be the same as (* x (/ y)),
  and in particular, for (/ 0 0.0) to be the same as (* 0 (/ 0.0)),
  which reduces to (* 0 +inf.0).  Therefore (* 0 +inf.0) should return
  a NaN.

* test-suite/tests/numbers.test: Add many multiplication tests.

* NEWS: Add NEWS entry.
2011-02-01 21:11:12 +01:00
Mark H Weaver
55a8b70819 More discriminating NaN predicates for numbers.test
* test-suite/tests/numbers.test: (real-nan?, complex-nan?,
  imaginary-nan?): Add more discriminating NaN testing predicates
  internal to numbers.test, and convert several uses of `nan?'
  to use these instead:
   * `real-nan?' checks that its argument is real and a NaN.
   * `complex-nan?' checks that both the real and imaginary
                    parts of its argument are NaNs.
   * `imaginary-nan?' checks that its argument's real part
                      is zero and the imaginary part is a NaN.
2011-02-01 21:09:36 +01:00
Mark H Weaver
605f698026 Fix bugs in `rationalize'
* libguile/numbers.c (scm_rationalize): Fix bugs.  Previously, it
  returned exact integers unmodified, although that was incorrect if
  the epsilon was at least 1 or inexact, e.g. (rationalize 4 1) should
  return 3 per R5RS and R6RS, but previously it returned 4.  Also
  handle cases involving infinities and NaNs properly, per R6RS.

* test-suite/tests/numbers.test: Add test cases for `rationalize'.

* NEWS: Add NEWS entry
2011-02-01 21:08:52 +01:00
Mark H Weaver
bfe1f03aac Improve extensibility of expt' and integer-expt'
* libguile/numbers.c (scm_integer_expt): No longer require that the
  first argument be a number, in order to improve extensibility.  This
  allows us to efficiently raise arbitrary objects to an integer power
  as long as we can multiply those objects.  For example, this allows us
  to efficiently exponentiate matrices if we define only multiplication
  methods for matrices.  Note also that scm_expt calls this procedure
  whenever the exponent is an integer, regardless of the type of the
  first argument.  Also rearrange the order in which we test special
  cases.

* test-suite/tests/numbers.test (expt, integer-expt): Comment out tests
  that required `(expt #t 0)' and `(integer-expt #t 0)' to throw
  exceptions.  Add tests for (expt #t 2) and `(integer-expt #t 2)
  instead.

* NEWS: Add NEWS entry
2011-01-31 21:58:27 +01:00
Mark H Weaver
a8591a55f0 Rework the testing framework for number-theoretic division operators
* test-suite/tests/numbers.test (test-eqv?): Remove special handling of
  zeroes.  Zeroes are now compared like all other numbers.  Exact
  numbers are compared with `eqv?' and inexact numbers are compared to
  within test-epsilon.

  Rework the testing framework for number-theoretic division operators:
  `euclidean/', `euclidean-quotient', `euclidean-remainder',
  `centered/', `centered-quotient', and `centered-remainder'.
  Previously we compared all test results against a simple scheme
  implementation of the same operations.  However, these operations have
  discontinuous jumps where a tiny change in the inputs can lead to a
  large change in the outputs, e.g.:

    (euclidean/ 130.00000000000 10/7) ==> 91.0 and 0.0
    (euclidean/ 129.99999999999 10/7) ==> 90.0 and 1.42857142856141

  In the new testing scheme, we compare values against the simple
  implementations only if the input arguments contain an infinity or a
  NaN.  In the common case of two finite arguments, we simply make sure
  that the outputs of all three operators (e.g. `euclidean/',
  `euclidean-quotient', `euclidean-remainder') equal each other, that
  outputs are exact iff both inputs are exact, and that the required
  properties of the operator are met: that Q is an integer, that R is
  within the specified range, and that N = Q*D + R.
2011-01-31 09:51:02 +01:00
Mark H Weaver
2519490c50 Improve extensibility of core numeric procedures
* libguile/numbers.c (scm_quotient, scm_remainder, scm_modulo,
  scm_zero_p, scm_positive_p, scm_negative_p, scm_real_part,
  scm_imag_part, scm_numerator, scm_denominator, scm_magnitude,
  scm_angle, scm_exact_to_inexact): Change from SCM_GPROC to
  SCM_PRIMITIVE_GENERIC.  As a side effect, all of these procedures now
  have documentation strings.

  (scm_exact_p, scm_inexact_p, scm_odd_p, scm_even_p, scm_finite_p,
  scm_inf_p, scm_nan_p, scm_expt, scm_inexact_to_exact, scm_log,
  scm_log10, scm_exp, scm_sqrt): Change from SCM_DEFINE to
  SCM_PRIMITIVE_GENERIC, and make sure the code allows these functions
  to be extended in practice.

  (scm_real_part, scm_imag_part, scm_numerator, scm_denominator,
  scm_inexact_to_exact): Simplify type dispatch code.

  (scm_sqrt): Rename formal argument from x to z, since complex numbers
  are supported.

  (scm_abs): Fix empty FUNC_NAME.

* libguile/numbers.h (scm_finite_p): Add missing prototype.

  (scm_inf_p, scm_nan_p): Rename formal parameter from n to x, since
  the domain is the real numbers.

* test-suite/tests/numbers.test: Test for documentation strings.  Change
  from `expect-fail' to `pass-if' for several of these, and add tests
  for others.  Also add other tests for `real-part' and `imag-part',
  which previously had none.
2011-01-30 23:06:07 +01:00