patterncppMinor
Printing doubles using string manipulation
Viewed 0 times
doublesprintingmanipulationusingstring
Problem
Having mostly used Qt and its classes like
The code is for printing
QString, I wrote a little exercise with plain C++11. I'm looking for two kinds of input: generally improving the code and/or doing it better in an entirely different way (still standard C++11 or C++14, no Boost or anything).The code is for printing
doubles with given number of significant digits, by first producing a string using scientific notation, and then manipulating that string to move the dot and pad it with zeros.#include
#include
#include
#include
#include
#include
template
std::string number_to_sci_string(T number, int precision) {
std::stringstream ss;
ss = s.length()-1 || // must not be last
e_pos - dot_pos (part2.length());
if (exponent >= part2length) {
auto fill = std::string(exponent - part2length, '0');
return part1 + part2 + fill;
}
else if (exponent nums{ -2000.0005, -1.2345234, -0.000011345, 0, 0.0000001, 0.1342134, 1.1234, 10000 };
for_each(nums.begin(), nums.end(), [](double &n) {
string sci = number_to_sci_string(n, 5);
string nor = sci_string_to_normal(sci);
cout << n << ": " << sci << " == " << nor << endl;
});
}Solution
-
Also, I really wonder why you are using a different notion of precision than the standard library...
-
I suggest you be a bit more flexible in what you accept:
-
Don't use
-
The opening brace of
-
Prefer the for-range-loop to
number_to_sci_string looks ok, though you could considerably improve performance by chucking the template, restricting to float, double and long double and using snprintf:std::string number_to_sci_string(long double number, int precision) {
std::string s(std::snprintf(0, 0, "%.*Le", precision-1, number), '\0');
std::snprintf(&s[0], s.size()+1, "%.*Le", precision-1, number);
return s;
}Also, I really wonder why you are using a different notion of precision than the standard library...
-
I suggest you be a bit more flexible in what you accept:
- The exponent
e00should be optional.
- The fractional part (and decimal point)
.00should be optional.
- If there's a fractional part, the integer part should be optional.
-
Don't use
using namespace std;, even in the implementation-file: You don't control what symbols it contains, and there are no guarantees none are added.-
The opening brace of
main()'s body is, in contrast to all other functions, on a separate line. Why?-
Prefer the for-range-loop to
std::for_each+lambda. The compiler should compile both to the same result, but the former is simpler and looks better.Code Snippets
std::string number_to_sci_string(long double number, int precision) {
std::string s(std::snprintf(0, 0, "%.*Le", precision-1, number), '\0');
std::snprintf(&s[0], s.size()+1, "%.*Le", precision-1, number);
return s;
}Context
StackExchange Code Review Q#110496, answer score: 3
Revisions (0)
No revisions yet.