2

I'm building my own string class and I'm trying to use this function to convert a numerical string to an integer:

int String::convertToInt() const {  
    int exp = length() - 1;
    int result = 0;

    for(int i = 0; i < length(); ++i) {
        result += (charAt(i) - '0') * (10 ^ exp);
        --exp;
    }   
    return result;
}

Something isn't working right, but I can't pick out what it is. When I try to convert "49" to an int, it converts it to 134.

uberpirate
  • 33
  • 5
  • possible duplicate of [How does atoi() function in C++ work?](http://stackoverflow.com/questions/5710091/how-does-atoi-function-in-c-work) – David Nov 01 '13 at 13:27
  • Have you looked at 'atoi' or 'strtol'/'strtoul'? – kfsone Nov 02 '13 at 04:36

3 Answers3

9

^ is XOR. I believe you're looking for std::pow(10, exp).

Or even this:

int String::convertToInt() const {  
    int order = std::pow(10, length() - 1);
    int result = 0;

    for(int i = 0; i < length(); ++i) {
        result += (charAt(i) - '0') * order;
        order /= 10;
    }   
    return result;
}
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • @MSalters Better now? I was typing the edit as you commented. Of course the canonical approach here is Horner (+1'd your answer for that), but I was trying to stick close to the OP's code. – Angew is no longer proud of SO Nov 01 '13 at 13:34
  • The problem is that `std::pow` isn't exactly fast, it uses floating-point math. Similarly, integer division isn't that fast either. You'd be better off starting with `i=length()-1` and `order=1`, then doing `order *= 10` and `--i`. – MSalters Nov 01 '13 at 13:37
3

The easiest way is to realize that 49 is 4 * 10 + 9, and 493 similarly is 49 * 10 + 3.

That is to say, the result is 10 times the first N-1 digits plus the last digit. You can write that as a loop or as a recursive function. Stack depth won't hurt you; after about 20 digits you'd overflow even a 64 bits result. So

int String::convertToInt() const {
    if (empty()) return 0; // Recursive functions better terminate.
    // TODO: negative numbers.  
    return 10 * convertToInt(substr(0, length()-1)) + (back() - '0');
}

or

int String::convertToInt() const {
    // TODO: negative numbers.  
    int result = 0;

    for(int i = 0; i < length(); ++i) {
        result * = 10;
        result += (charAt(i) - '0');
    }   
    return result;
}
MSalters
  • 173,980
  • 10
  • 155
  • 350
0

A more efficient approach would be:

// I know you said you are using something else
// but the same principle applies here
std::string s = "12345";

unsigned int result = 0;
unsigned int place = 1;
for (std::size_t i = s.length() - 1; i >= 0; --i, place *= 10)
{
    result += (s[i] - '0') * place;
}

Basically, you start at the right-most character and work your way left. Each character you move left, you multiply your place by 10 (very similar to how most of us learned to do addition growing up: add your 1's ... add your 10's ... add your 100's ... etc.). This also assumes that you already know the string contains nothing but numeric characters ('0'-'9').

Zac Howland
  • 15,777
  • 1
  • 26
  • 42