# HG changeset patch # User John W. Eaton # Date 1403304938 14400 # Node ID 47d4b680d0e07f39e32c1c676cbaa5f785208f2f # Parent 479d1d3cb5c33fb8713b35e497d141bb97a5f134 improve accuracy of range/scalar arithmetic (bug #42589) * Range.h, Range.cc (Range::Range (double, double, double, octave_idx_type): New protected constructor. (operator -, operator +, operator *): Use new constructor. (Range::Range (double, double, octave_idx_type): Also check that the limit remains finite. diff -r 479d1d3cb5c3 -r 47d4b680d0e0 liboctave/array/Range.cc --- a/liboctave/array/Range.cc Thu Jun 19 18:08:00 2014 -0400 +++ b/liboctave/array/Range.cc Fri Jun 20 18:55:38 2014 -0400 @@ -387,12 +387,12 @@ Range operator - (const Range& r) { - return Range (-r.base (), -r.inc (), r.nelem ()); + return Range (-r.base (), -r.limit (), -r.inc (), r.nelem ()); } Range operator + (double x, const Range& r) { - Range result (x + r.base (), r.inc (), r.nelem ()); + Range result (x + r.base (), x + r.limit (), r.inc (), r.nelem ()); if (result.rng_nelem < 0) result.cache = x + r.matrix_value (); @@ -401,7 +401,7 @@ Range operator + (const Range& r, double x) { - Range result (r.base () + x, r.inc (), r.nelem ()); + Range result (r.base () + x, r.limit () + x, r.inc (), r.nelem ()); if (result.rng_nelem < 0) result.cache = r.matrix_value () + x; @@ -410,7 +410,7 @@ Range operator - (double x, const Range& r) { - Range result (x - r.base (), -r.inc (), r.nelem ()); + Range result (x - r.base (), x - r.limit (), -r.inc (), r.nelem ()); if (result.rng_nelem < 0) result.cache = x - r.matrix_value (); @@ -419,7 +419,7 @@ Range operator - (const Range& r, double x) { - Range result (r.base () - x, r.inc (), r.nelem ()); + Range result (r.base () - x, r.limit () - x, r.inc (), r.nelem ()); if (result.rng_nelem < 0) result.cache = r.matrix_value () - x; @@ -428,7 +428,7 @@ Range operator * (double x, const Range& r) { - Range result (x * r.base (), x * r.inc (), r.nelem ()); + Range result (x * r.base (), x * r.limit (), x * r.inc (), r.nelem ()); if (result.rng_nelem < 0) result.cache = x * r.matrix_value (); @@ -437,7 +437,7 @@ Range operator * (const Range& r, double x) { - Range result (r.base () * x, r.inc () * x, r.nelem ()); + Range result (r.base () * x, r.limit () * x, r.inc () * x, r.nelem ()); if (result.rng_nelem < 0) result.cache = r.matrix_value () * x; diff -r 479d1d3cb5c3 -r 47d4b680d0e0 liboctave/array/Range.h --- a/liboctave/array/Range.h Thu Jun 19 18:08:00 2014 -0400 +++ b/liboctave/array/Range.h Fri Jun 20 18:55:38 2014 -0400 @@ -54,7 +54,7 @@ : rng_base (b), rng_limit (b + (n-1) * i), rng_inc (i), rng_nelem (n), cache () { - if (! xfinite (b) || ! xfinite (i)) + if (! xfinite (b) || ! xfinite (i) | ! xfinite (rng_limit)) rng_nelem = -2; } @@ -145,6 +145,16 @@ void clear_cache (void) const { cache.resize (0, 0); } +protected: + + // For operators' usage (to allow all values to be set directly). + Range (double b, double l, double i, octave_idx_type n) + : rng_base (b), rng_limit (l), rng_inc (i), + rng_nelem (n), cache () + { + if (! xfinite (b) || ! xfinite (i) || ! xfinite (l)) + rng_nelem = -2; + } }; extern OCTAVE_API Range operator - (const Range& r);