Is it possible to parse a string to a double with only 1 pass

  • Thread starter Jamin2112
  • Start date
  • Tags
    String
In summary: At the end, set x = x / 10^k. Option #3: (Best): Use std::stod from #include <string> (new with c++11). This is just a wrapper around std::strtod, but with a more c++ like interface.This is actually a lot trickier than it sounds, unless you're allowed to lose the last couple bits of precision. See this answer on stackoverflow.In summary, using std::stod instead of std::strtod from #include <string> is more complicated, but can be done in one pass with less precision loss.
  • #1
Jamin2112
986
12
through the string?

I'm at a point in a program I'm making where I have a string representation of a valid decimal representation of a double. By "valid representation" I mean that it contains only characters in the set {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.'} with no more than 1 of '.'. I want to convert it to a double.

Here's the problem: The only procedure I can think of would require knowing in advance where the decimal place is. Or is there another way?
 
Technology news on Phys.org
  • #2
Starting from the first character in the string s, and using c(s) to represent the character at the current position in the string
Code:
0. Set x to 0
1. If c(s) != '.'
   1a. x *= 10
   1b. add c(s) to x
   1c. advance to next character
   1d. go to 1
2. (Code to treat the decimals)
 
  • #3
For each digit, accumulate the converted value with x = 10*x + d.
Count the number of digits k after the '.' as you wotk along the string.
At the end, set x = x / 10^k.

That isn't the best possible way to do it, because you will get unnecessary roundimg errors with a string like 1.0000000000000000000000000000000000000000000000000 (with more than 16 0's after the decimal point).

Fixing that is left as an exercise - you can still do it in one pass :smile:
 
Last edited:
  • #4
Jamin2112 said:
Here's the problem: The only procedure I can think of would require knowing in advance where the decimal place is. Or is there another way?
Option #1: Just search for the period and be done with it. Your obsessing about small optimizations is in creating disoptimizations. If you find that period (which is fast; std::string::find) you now have two integers to parse. That's fast. Parsing one character at a time is slow, and is also going to hurt accuracy. The goal in the parsing should be to be within half an ULP. A one character at a time parser isn't going to attain that.

Option #2: (Better): use std::strtod from #include <cstdlib>. This has nice hooks for error handling (which you can ignore at the start), it knows all the different ways doubles can be represented, and it knows all the little gotchas with those representations. Use the standard library. Don't reinvent the wheel.

Option #3: (Best): Use std::stod from #include <string> (new with c++11). This is just a wrapper around std::strtod, but with a more c++ like interface.
 
  • #5
This is actually a lot trickier than it sounds, unless you're allowed to lose the last couple bits of precision. See this answer on stackoverflow.

If you're fine with losing bits of precision, just start with a double total of 0. Then iteratively multiply by ten and adding the current digit into the total until you hit the decimal point. Then start iteratively dividing a scale factor (starting from 1) by ten then adding the current digit multiplied by the scale factor into the total. You'll lose precision when dividing by ten, and also there will be rounding in the additions. But, like I said, avoiding that entirely is hard.
 
  • #6
Or just use the library functions described in post #4. Or

Option #4: Use a std::stringstream from #include <sstream>.
 
  • #7
You really should consider reading 'What every computer scientist should know about floating point' By David Goldberg.

https://ece.uwaterloo.ca/~dwharder/NumericalAnalysis/02Numerics/Double/paper.pdf.

An ULP is the ultimate limit of precision. I am defining ULP minimally since D H mentions it, and it seems possible that because of the way you phrased your question you may not know about it.

Some C compilers support the Decimal datatype, which is a floating representation without the binary floating point problems.
 
  • #8
jim mcnamara said:
An ULP is the ultimate limit of precision.
Or unit of least precision. Or unit in the last place. They're all ULP, there's a tiny angel dancing on the point of a needle distinction between some of these.

Think of that tiny dancing angel as an ULP.
 
  • #9
jim mcnamara said:
Some C compilers support the Decimal datatype, which is a floating representation without the binary floating point problems.

Except that it probably just swaps the binary floating point problems for a different set.

For example the IBM 360 and 370 mainframes worked in floating point to base 16 not base 2, which had some "interesting" consequences - like calculating the mean of a set of n numbers by adding them and dividing by n, and getting a result that was outside of the range of the largest and smallest input numbers. (And that "interesting mathematical result" didn't involve any underflows or overflows).
 
  • #11
If the length of the string is known in advance, then the string could be scanned backwards to reduce the loss of precision. You'd could assume the string is an integer until and/or unless a '.' is encountered.
 

FAQ: Is it possible to parse a string to a double with only 1 pass

1. Can a string be converted to a double with only one pass?

Yes, it is possible to convert a string to a double with only one pass. This means that the string is read and converted to a double in a single iteration, without having to go back and re-read the string.

2. What does it mean to "parse" a string to a double?

Parsing a string to a double means converting a string of characters into a numerical value that can be used in mathematical operations. In this case, it involves converting the string to a double data type.

3. Why is it important to be able to parse a string to a double with only one pass?

Parsing a string to a double with only one pass is important because it saves time and resources. It eliminates the need for multiple iterations and can improve the efficiency of a program.

4. Are there any limitations to parsing a string to a double with only one pass?

Yes, there may be limitations depending on the programming language and the specific implementation. Some languages may not have built-in methods for parsing strings to doubles in one pass, while others may have restrictions on the size or format of the string that can be converted.

5. How can I ensure that a string is parsed to a double with only one pass?

The best way to ensure that a string is parsed to a double with only one pass is to use a programming language or method that specifically allows for this. It is important to carefully read the documentation and understand the limitations of the method being used.

Similar threads

Replies
34
Views
3K
Replies
17
Views
1K
Replies
3
Views
1K
Replies
9
Views
2K
Replies
89
Views
5K
Replies
23
Views
2K
Replies
5
Views
3K
Replies
7
Views
1K
Back
Top