1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-01 20:30:28 +02:00
Commit graph

152 commits

Author SHA1 Message Date
Daniel Llorens
54c4753dd3 Add missing branch in scm_is_less_than()
Fixes https://debbugs.gnu.org/69725.

* libguile/numbers.c (scm_is_less_than): Add branch for (< fraction real).
* test-suite/tests/numbers.test (<): New test.
2024-03-19 16:03:09 +01:00
Daniel Llorens
19bc021e34 Have log and log10(real nan) return real nan regardless of sign
* libguile/numbers.c (log_of_shifted_double, scm_log10): Avoid complex
  extension when the argument is a real nan.
* test-suite/tests/numbers.test: Tests for nans of either sign.
2022-01-13 09:37:17 +01:00
Daniel Llorens
bf9d30f3c3 Limit the range of ash, round-ash count argument to INT32
This avoids gmp aborting e.g. with (ash 1 (expt 2 37)). The new limit is
such that (ash 1 (expt 30)) is accepted but (ash 1 (expt 31)) throws.

Fixes https://bugs.gnu.org/48150

* libguile/numbers.c (ash, round-ash): As stated.
* test-suite/tests/numbers.test: Test a case known to make gmp abort before.
2021-11-05 10:26:43 +01:00
Ludovic Courtès
74abae04aa Baseline compiler no longer swaps rsh/lsh when transforming ash calls.
Reported by Marius Bakke <marius@gnu.org>
at <https://issues.guix.gnu.org/50696>.

Previously, the baseline compiler would incorrectly emit a right shift
when for, say, (ash x 2), and a left shift for (ash x -2).

* module/language/tree-il/compile-bytecode.scm (canonicalize): When Y is
negative, emit 'rsh', not 'lsh'.
* test-suite/tests/numbers.test ("ash at -O1"): New test.
2021-09-20 23:27:39 +02:00
Mark H Weaver
00973cbd2e In 'ash' and 'round-ash', handle right shift count of LONG_MIN.
Fixes <https://bugs.gnu.org/21901>.
Reported by Zefram <zefram@fysh.org>.

* libguile/numbers.c: Add another top-level 'verify' to ensure that
LONG_MIN is not a fixnum.
(scm_ash, scm_round_ash): Ensure that when the shift count is LONG_MIN,
it is not handled via the normal code path, to avoid signed overflow
when the shift count is negated.
* test-suite/tests/numbers.test: Add tests.
2019-05-23 16:09:45 +02:00
Mark H Weaver
e6100f64bb Fix 'round-ash' of negative integers by huge right shift counts.
This is a followup to commit 011aec7e24.

When rounding, right shifting a negative integer by a huge shift count
results in 0, not -1.

* libguile/numbers.c: Add top-level 'verify' to ensure that the
assumptions in 'scm_ash' and 'scm_round_ash' are valid.
(scm_round_ash): In the case that handles huge right shifts, require
that the shift count _exceeds_ the integer length, and return 0 instead
of -1.
* test-suite/tests/numbers.test: Adjust tests accordingly.
2019-05-23 16:09:41 +02:00
Mark H Weaver
e4c5f73f94 Gracefully handle huge shift counts in 'ash' and 'round-ash'.
Fixes <https://bugs.gnu.org/32644>.
Reported by Stefan Israelsson Tampe <stefan.itampe@gmail.com>.

The need for this arose because the type inferrer for 'ursh' sometimes
passes (- 1 (expt 2 64)) as the second argument to 'ash'.

* libguile/numbers.c (scm_ash, scm_round_ash): Gracefully handle several
cases where the shift count does not fit in a C 'long'.
* test-suite/tests/numbers.test: Add tests.
2019-05-23 16:08:12 +02:00
Daniel Llorens
7de77bf7d8 Fix bug in comparison between real and complex
This bug was introduced by 35a9059250.

* module/language/cps/specialize-numbers.scm (specialize-operations):
  Check that both operands are real as a condition for
  specialize-f64-comparison.
* test-suite/tests/numbers.test: Add test.
2017-03-09 15:17:35 +01:00
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