Reputation: 2962
I am trying to convert a vector of int to an int. This is how I proceed:
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
uint32_t toInt(vector<int> v)
{
uint32_t x=0;
for(int i=0 ; i<v.size() ; i++)
x+=v[i]*pow(10, v.size()-1-i);
return x;
}
int main()
{
vector<int> v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
cout << toInt(v) << endl; // displays: 123456787 (???)
}
The program should output 123456789, but instead I have 12345678(!)7(!).
I am using GCC (tdm-1) 4.7.1 on Code::Blocks 13.12
Does someone have an explanation to this problem, and a way to solve it ? Thank you.
Upvotes: 0
Views: 122
Reputation: 33962
The exact cause of this I'm unable to reproduce, but one simple solution is to not use pow
:
#include <iostream>
#include <vector>
uint32_t toInt(std::vector<int> v)
{
uint32_t x=0;
for(size_t i=0 ; i<v.size() ; i++)
{
x*=10;
x+=v[i];
}
return x;
}
int main()
{
std::vector<int> v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
std::cout << toInt(v) << std::endl;
}
pow
pow
is designed to compute powers of floating point numbers and as a result it does some complex and expensive things. If you are merely getting the power of an integer to an integer, it is almost always faster to multiply.
pow
and std::pow
are subtly different. std::pow
is a templated beast that ultimately calls pow
, but only after playing casting games with the input data types and can lead to odd results. Case in point, what this questioner ran into: C++ pow unusual type conversion
This is but one of the many ways using namespace std;
can get you. You might be surprised by which pow
the compiler selected. Read more here: Why is "using namespace std" considered bad practice?
Upvotes: 1
Reputation: 150
Your code works fine on my computer
uint32_t toInt(vector<int> v)
{
uint32_t x=0;
for(int i=0 ; i<v.size() ; i++)
x+=v[i]*pow(10, v.size()-1-i);
return x;
}
int main(){
int myints[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
vector<int> v (myints, myints + sizeof(myints) / sizeof(int) );
cout << toInt(v) << endl;
}
which excute like:
./test 123456789 Exit code: 0
This computer is old and runs c++98 but I dont see any reason your program doesn't work. Check your memory for overflow maybe.
Upvotes: 0
Reputation: 490623
I can't imagine it leading to the problem you've cited, but the way you're doing the conversion is pretty ugly, and involves floating point math, so it could lead to at least some degree of inaccuracy in some cases.
You could eliminate that particular problem by doing the conversion a little differently. For example:
int toInt(vector<int> const &v) { // pass by reference to avoid copying
int ret = 0;
for (int i=0; i<v.size(); i++)
ret = 10 * ret + v[i];
return ret;
}
Or, you could use the standard library to handle more of the work for you:
int toInt(vector<int> const &v) { // pass by reference to avoid copying
return std::accumulate(v.begin(), v.end(),
0,
[](int v, int digit) { return 10 * v + digit; });
}
Of course, this is still limited to values that will fit in an int
--around 2 billion for a typical 32-bit int
, for example.
Upvotes: 4