octave-bug-tracker
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Octave-bug-tracker] [bug #62968] idx_vector constructor m_len calculati


From: Maged Rifaat
Subject: [Octave-bug-tracker] [bug #62968] idx_vector constructor m_len calculation is incorret
Date: Sat, 27 Aug 2022 07:37:35 -0400 (EDT)

URL:
  <https://savannah.gnu.org/bugs/?62968>

                 Summary: idx_vector constructor m_len calculation is incorret
                 Project: GNU Octave
               Submitter: magedrifaat
               Submitted: Sat 27 Aug 2022 11:37:34 AM UTC
                Category: Interpreter
                Severity: 3 - Normal
                Priority: 5 - Normal
              Item Group: Incorrect Result
                  Status: None
             Assigned to: None
         Originator Name: 
        Originator Email: 
             Open/Closed: Open
                 Release: 7.2.0
         Discussion Lock: Any
        Operating System: GNU/Linux


    _______________________________________________________

Follow-up Comments:


-------------------------------------------------------
Date: Sat 27 Aug 2022 11:37:34 AM UTC By: Maged Rifaat <magedrifaat>
Among the many constructors of idx_vector, there is a constructor that accepts
start, limit and step:

idx_vector (octave_idx_type start, octave_idx_type limit,
            octave_idx_type step = 1)
  : m_rep (new idx_range_rep (start, limit, step)) { }


However using this constructor with a step of 2 or higher can result in wrong
number of elements, for example:

idx_vector i = idx_vector (1, 10, 2);

Will create a vector of 4 elements only (1, 3, 5, 7) instead of the expected 5
elements (1, 3, 5, 7, 9).

Tracing this constructor I found a calculation error in the underlying
idx_range_rep constructor:

idx_vector::idx_range_rep::idx_range_rep (octave_idx_type start,
                                          octave_idx_type limit,
                                          octave_idx_type step)
  : idx_base_rep (), m_start(start),
    m_len (step ? std::max ((limit - start) / step,
                            static_cast<octave_idx_type> (0))
           : -1),
    m_step (step)

Essentially the calculation for m_len is (limit - start) / step. I think this
is incorrect as it doesn't account for cases where the limit is not aligned
with the step.

If i got this right, the correct calculation would be a rounding up, and since
all operands are integers it can be done like this:

m_len = (limit - start + step - 1) / step;


My reasoning here is that the number of _step_ intervals existing between
start and limit needn't be a whole number because we only need the first
number in this interval so any fraction means we at least have this first
number so we can round up and count it as a whole interval.

But this doesn't account for negative _step_, so instead of rounding up we
need to round away from zero:

if (step > 0)
  m_len = (limit - start + step - 1) / step;
else
  m_len = (limit - start + step + 1) / step;


This constructor doesn't seem to be ever used with a step >= 2 anywhere in
Octave's core that I can find so I don't think any of the existing code is
affected by this bug.







    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?62968>

_______________________________________________
Message sent via Savannah
https://savannah.gnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]