Padding a vector with 0's if it's not a multiple of 8
Asked Answered
A

4

8

How can I pad out a vector with 0's if it is not a multiple of 8 bytes? In the following code I work out the offset and add to the vector to make sure it always has 8 values. I would like to pad this out with 0's and I am wondering what is the most efficient way to do this.

For example:

Input: 4444

With padding: 4444000000000000

The code I have so far is:

if ((vector1.size() % 8) != 0)
{
  for (std::vector<unsigned char>::iterator itr = vector1.begin(); itr != vector1.end(); itr ++)
  {
    vector1.push_back(fmod(vector1.size(), 8));

    if(vector1.size() == 8)
      break;
  }
}
Araiza answered 25/9, 2017 at 13:26 Comment(1)
Number of 0 to add is (8 - (vector1.size() % 8)) % 8 Without the last % 8 a vector that is already of length 8 would get another 8 0s added.Collar
I
20

UPDATE: One-liner (original more readable version below):

vec.resize(vec.size() + (8 - vec.size() % 8) % 8, 0);

Here's the code that should be quite efficient. It avoids multiple re-allocations and does nothing if no padding is needed.

const size_t nonPaddedSize = vec.size();
const size_t numPaddingElements = (8 - nonPaddedSize % 8) % 8;
if(numPaddingElements > 0)
    vec.resize(nonPaddedSize + numPaddingElements, 0);

Here's a live-example


Note: Originally the post suggested reserve + insert, but resize will do the same in a less verbose way.

Ihs answered 25/9, 2017 at 13:39 Comment(3)
This works perfectly, therefore I am accepting this answer. Thank you AMA.Araiza
@Araiza I'm glad it helped.Ihs
Nice: this is a touchstone for your knowledge of using subtraction with unsigned types.Dismount
D
8

What's wrong with the trivial

while (vector1.size() % 8){
    vector1.push_back(0);
}

which will append zeros until the number of elements is a multiple of 8?

The potential for re-allocation is a red herring here given how you're making up the size.

Dismount answered 25/9, 2017 at 13:29 Comment(1)
Up-voted since the last sentence is very pertinent. Amortized constant push_back and the choice of sizes should play well together.Grapheme
D
4

For a std::vector you can use insert:

iterator insert( const_iterator pos, size_type count, const T& value );

(previously void insert( iterator pos, size_type count, const T& value );)

Work out how many 0s you want to add, then insert them at the end.

Despondency answered 25/9, 2017 at 13:29 Comment(0)
Y
3

How about:

constexpr std::size_t ceil_to_multiple(std::size_t n, std::size_t mul)
{
    return (n + mul - 1) / mul * mul;
}

and then

vector1.resize(ceil_to_multiple(vector1.size(), 8), 0);
Yoke answered 25/9, 2017 at 14:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.