Better size aligning?

I have the following two vectors in C++11:

vector<unsigned char> left = { 1, 2, 3, 4, 5, 6 }; // it is meant to represent the number: 123456
vector<unsigned char> right = { 1, 2, 3, 4 }; // meant to be number: 1234


After a function processes them, they become:

left = { 6, 5, 4, 3, 2, 1 };
right = { 4, 3, 2, 1 };


Now, I need to complete the shorter one with zeros at the end until they are equal in size(). I have thefollowing method:

void bigint::process_operands( vector<unsigned char> & left, vector<unsigned char> & right )
{
size_t left_size = left.size();
size_t right_size = right.size();

if( left_size < right_size )
{
size_t size_diff = right_size - left_size;

for( size_t i = 0; i != size_diff; ++i )
left.push_back( '0' );
} else if( right_size < left_size )
{
size_t size_diff = left_size - right_size;

for( size_t i = 0; i != size_diff; ++i )
right.push_back( '0' );
}
}


Is there any better implementation?

-

auto sz = std::max(left.size(), right.size());
left.resize(sz, '0');
right.resize(sz, '0');


.resize() will resize the container to the given size, and fill the new elements (if any) with the given value.

-
I am not sure abut its performance, but it compiles... – Victor Mar 10 '14 at 8:44
@Victor What are you unsure about? It's at least as efficient as (probably more than) using back_inserter or push_back. If you're worried about max, replace it with a conditional (although it's almost guaranteed to get inlined). – AlchemicalApples Mar 10 '14 at 19:15

Firstly, given that you're using vector without namespace qualification (that is, not as std::vector), I assume you have a using namespace std; in this code. This is generally a bad idea, but especially so in this case. You use vector<unsigned char> & right (and vector<unsigned char> left), however, there is a std::right (and a std::left) defined in <ios>. This could potentially lead to some very confusing compiler errors.

Using a few tricks from <algorithm>, we can shorten the above code considerably.

void bigint::process_operands(vector<unsigned char> & left_, vector<unsigned char> & right_)
{
auto& shorter = (left_.size() < right_.size()) ? left_ : right_;
std::fill_n(std::back_inserter(shorter), std::abs(left_.size() - right_.size()), '0');
}


This is much more terse, but I find that using the standard library actually makes this code easier to read and more clear as to exactly what it is doing.

-

I’d just like to point out a very short version of your own code. It is certainly not as C++ish as a vector::insert or fill_n solution, but what it does is pretty obvious.

void bigint::process_operands( vector<unsigned char> & left, vector<unsigned char> & right )
{
while (left.size() < right.size())
left.push_back( '0' );
while (right.size() < left.size())
right.push_back( '0' );
}

-