Mercurial > octave
diff liboctave/array/Range.cc @ 28592:e70c859c4bff
allow infinite limits on for loop ranges (bug #45143)
* ov.cc (octave_value::octave_value (const Range&, bool)):
If force_range is false, throw error if range is not OK.
* Range.h, Range.cc (Range::ok): New function.
(Range::numel_internal): Return one less than the maximum possible
octave_idx_type value if infinite range is detected.
(Range::init): Don't set m_limit if limit is infinite.
(Range::Range (double, double)): Likewise.
(Range::Range (double, double, double)): Likewise.
(Range::Range (double, double, octave_idx_type):
Trust supplied value of numel.
* for.tst: New tests.
* pt-eval.cc (tree_evaluator::visit_simple_for_command): Warn if range
limit is infinite.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 24 Jul 2020 01:01:35 -0400 |
parents | 455fe4a6f22c |
children | 83172e1c77f2 |
line wrap: on
line diff
--- a/liboctave/array/Range.cc Tue Jul 21 17:05:15 2020 -0400 +++ b/liboctave/array/Range.cc Fri Jul 24 01:01:35 2020 -0400 @@ -527,9 +527,16 @@ { octave_idx_type retval = -1; - if (m_inc == 0 - || (m_limit > m_base && m_inc < 0) - || (m_limit < m_base && m_inc > 0)) + if (! octave::math::isfinite (m_base) || ! octave::math::isfinite (m_inc) + || octave::math::isnan (m_limit)) + retval = -2; + else if (octave::math::isinf (m_limit) + && ((m_inc > 0 && m_limit > 0) + || (m_inc < 0 && m_limit < 0))) + retval = std::numeric_limits<octave_idx_type>::max () - 1; + else if (m_inc == 0 + || (m_limit > m_base && m_inc < 0) + || (m_limit < m_base && m_inc > 0)) { retval = 0; } @@ -539,8 +546,8 @@ double tmp = tfloor ((m_limit - m_base + m_inc) / m_inc, ct); - octave_idx_type n_elt = (tmp > 0.0 ? static_cast<octave_idx_type> (tmp) - : 0); + octave_idx_type n_elt = (tmp > 0.0 + ? static_cast<octave_idx_type> (tmp) : 0); // If the final element that we would compute for the range is equal to // the limit of the range, or is an adjacent floating point number, @@ -559,8 +566,8 @@ n_elt++; } - retval = (n_elt < std::numeric_limits<octave_idx_type>::max () - 1) - ? n_elt : -1; + retval = ((n_elt < std::numeric_limits<octave_idx_type>::max ()) + ? n_elt : -1); } return retval; @@ -569,12 +576,7 @@ double Range::limit_internal (void) const { - double new_limit; - - if (m_inc > 0) - new_limit = max (); - else - new_limit = min (); + double new_limit = m_inc > 0 ? max () : min (); // If result must be an integer then force the new_limit to be one. if (all_elements_are_ints ()) @@ -587,5 +589,7 @@ Range::init (void) { m_numel = numel_internal (); - m_limit = limit_internal (); + + if (! octave::math::isinf (m_limit)) + m_limit = limit_internal (); }