What is wrong about this algorithm?/

Do you know of better ways? Can you post source code, if you do?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//Converts a double of base radix contained within a string 
//to an fundamental C++ double type.
#include <string>
#include <iostream>
#include <cmath>
double _string_to_double(std::string s,unsigned short radix){
double n = 0;
for (unsigned short x = s.size(), y = 0;x>0;)
if(!(s[--x] ^ '.'))
n/=pow(radix,s.size()-1-x), y+= s.size()-x;
else
    n+=( (s[x]- (s[x]<='9' ? '0':'0'+7)   ) * pow(radix,s.size()-1-x - y) );
return n;
}
int main(){
std::cout<<_string_to_double("10.A",16)<<std::endl;//Prints 16.625
std::cout<<_string_to_double("1001.1",2)<<std::endl;//Prints 9.5
std::cout<<_string_to_double("123.4",10)<<std::endl;//Prints 123.4
return 0;
}
Last edited on
What is wrong about this algorithm?
Do you know of better ways?

Do we have to guess what the algorithm ought to be doing?
I appologize. It converts a double of base radix contained within a string to an fundamental C++ double type.
That's strange way to test if a character is '.'. Plus, I'd expect you to have to maintain some kind of state as to which site of the . you are, so you can decide whether to shift right or left in base radix. I wouldn't expect it to work without it.

(s[x]<='9' ? '0':'0'+7)
That expression could be clearer, do you really need to use a magic number there?
Define "better"

You could make it easier to read and more robust (handling negatives, handling some errors), for example, by relying on standard library functions more:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
double string_to_double(std::string s, unsigned short radix)
{
    std::size_t decimal_pos = s.find('.');
    int decimals = 0;
    if(decimal_pos != std::string::npos)
    {
        s.erase(decimal_pos, 1);
        decimals = s.size() - decimal_pos;
    }
    size_t errpos;
    double answer = stoll(s, &errpos, radix) / std::pow(radix, decimals);;
    if(errpos < s.size())
        throw std::invalid_argument("parse error in string_to_double");
    return answer;
}


demo: http://ideone.com/QFfESx

If you want it to be as fast as possible, use a speed-oriented parsing library, such as boost.spirit (or at least, start by not making unnecessary copy of the string and not calling pow so much)
Last edited on
http://ideone.com/6Vp4wo
http://ideone.com/Cck4Z3

There's about a 0.01s difference between yours and mine, both iterating 100000 times.
Is there anything else i can do to make it faster? Except using a library.
Maybe there are some magical bitwise operations that can be applied?
Topic archived. No new replies allowed.