Search code examples
c++coptimizationatoi

If i have a fixed size char array of padded ascii digits which I know refers to an unsigned integer, what is the fastest way to convert it to such?


Suppose I have a char buf[12]; which I know will always have a right justified unsigned number padded on the left with spaces. So, for example: _________329 (where the _ stands for space). The fastest way I can think of parsing it is with something like this:

while (*buf == ' ') buf++;
atoi(buf);

but I was wondering if there was a faster way, particularly with atoi given that we know it is unsigned which atoi does not assume..


Solution

  • I assume the first char is reserved for a "potential sign" and is always "space"? Because otherwise, you would only need a char[11] instead of a char[12]. Anyway, fixed size allows manual loop unrolling:

    unsigned parse(const char(&b)[12])
    {
        return ((((((((((b[1] & 15))
                 * 10 + (b[2] & 15))
                 * 10 + (b[3] & 15))
                 * 10 + (b[4] & 15))
                 * 10 + (b[5] & 15))
                 * 10 + (b[6] & 15))
                 * 10 + (b[7] & 15))
                 * 10 + (b[8] & 15))
                 * 10 + (b[9] & 15))
                 * 10 + (b[10]& 15);
    }
    

    Note that the & 15 trick treats spaces and zeros the same and will work with both ASCII (space = 32, zero = 48) and EBCDIC (space = 48, zero = 240). I haven't checked out other character encodings yet :)

    Will this actually be faster or slower than atoi? The only way to find out is to measure. But I would probably stay with atoi in any case, because using a standard function always improves readability.