What is wrong about this algorithm?/

Apr 17, 2013 at 12:03pm
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 Apr 17, 2013 at 12:30pm
Apr 17, 2013 at 12:18pm
What is wrong about this algorithm?
Do you know of better ways?

Do we have to guess what the algorithm ought to be doing?
Apr 17, 2013 at 12:29pm
I appologize. It converts a double of base radix contained within a string to an fundamental C++ double type.
Apr 17, 2013 at 12:39pm
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?
Apr 17, 2013 at 12:42pm
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 Apr 17, 2013 at 12:43pm
Apr 17, 2013 at 7:23pm
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.