ios_base::fixed & truncating trailing zeroes - c++

When printing certain decimal numbers, rounding may occur (my present platform is the IBM iSeries). If I set ios_base::fixed, it does better but prints annoying trailing (and insignificant) zeroes. Anyone have a better way? For the platform I'm using, the output is this:
myval=100000
myval=99999.990000
myval as string =99999.990000
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <unistd.h>
#include <algorithm>
using namespace std;
// returns t
template<typename T> string toString(const T& val)
{
stringstream os;
os.setf(std::ios_base::fixed);
os << val;
return os.str();
}
class MyApp {
private :
public :
MyApp();
virtual ~MyApp();
void run();
operator bool() const { return true; }
};
MyApp::MyApp()
{
}
MyApp::~MyApp()
{
}
void MyApp::run()
{
double myval = 99999.99;
string myval_as_string = toString<double>(myval);
cout << "myval=" << myval << endl;
cout.setf(std::ios_base::fixed);
cout << "myval=" << myval << endl;
cout << "myval as string =" << myval_as_string << endl;
}
int main(int argc, char* argv[])
{
MyApp myApp;
myApp.run();
}

You're looking for precision and not fixed. precision will specify the maximum precision used but it will not automatically print more zeros so increase it as much as you need. fixed will force it out to as many zeros as precision is set to. If you have set fixed previously, you can reset it with ios_base::defaultfloat.
template<typename T> string toString(const T& val)
{
stringstream os;
os.precision(15);
os << val;
return os.str();
}
....
void MyApp::run()
{
double myval = 99999.99;
string myval_as_string = toString<double>(myval);
cout << "myval=" << myval << endl;
cout.precision(15);
cout << "myval=" << myval << endl;
cout << "myval as string =" << myval_as_string << endl;
}
For more info, you can check out the standard here: http://www.cplusplus.com/reference/ios/ios_base/precision/. Note the following line:
Using the default floating-point notation, the precision field
specifies the maximum number of meaningful digits to display in total
counting both those before and those after the decimal point. Notice
that it is not a minimum, and therefore it does not pad the displayed
number with trailing zeros if the number can be displayed with less
digits than the precision.

Related

Can I set a variable that will change the floatfield when using cout?

I want to be able to easily change the floatfield from scientific to fixed dependent on a condition, so my result would change from something like 3.000000e+00 to 3.0, using code that might look something like this:
some_datatype floatfield;
float number = 5.894
if (condition) {
floatfield = 'scientific';
} else floatfield = 'fixed';
cout << "hello" << floatfield << number << endl;
I'm aware I can achieve the same effect using
float number = 5.894
if (condition) {
cout << "hello" << scientific << number << endl;
} else cout << "hello" << fixed << number << endl;
But this does not generalise well if I start using more stream format flags.
If some_datatype exists, what is it? If not, is there any other way of changing the stream format flags using a condition?
I/O manipulators are actually functions (!), and the ones you want to switch between happen to have the same signature.
So, you can use a function pointer to achieve your goal:
#include <iomanip>
#include <iostream>
int main()
{
using ManipFuncType = std::ios_base&(std::ios_base&);
const bool condition = true; // or false!
ManipFuncType* floatfield;
float number = 5.894;
if (condition)
floatfield = std::scientific;
else
floatfield = std::fixed;
std::cout << "hello" << floatfield << number << std::endl;
}
(live demo)
I'm not sure I understood the question correctly, but this could be a solution:
#include <iostream>
using namespace std;
struct my_float {
float value_;
bool scientific_ = true;
my_float(float value) : value_(value) {}
void set_scientific() { scientific_ = true; }
void set_fixed() { scientific_ = false; }
};
ostream& operator<<(ostream& os, const my_float& f) {
if (f.scientific_)
return os << scientific << f.value_;
else
return os << fixed << f.value_;
}
int main() {
my_float number = 5.894;
bool condition = true; // <--- Change this!
if (condition) {
number.set_scientific();
}
else {
number.set_fixed();
}
cout << "hello" << number << endl;
return 0;
}
This is of course very crude, and the class could definitely be more complete.
Don't use this to store many floats, because id may easily double your memory requirements.

iomanip set at most 4 digits after decimal point

I want to print to screen some numbers with at most 4 digits after decimal point using iomanip.
I've learned that in default mode setprecision counts not only the digits after decimal point but also the digits in the integer part. This code
#include <iostream>
#include <iomanip>
int main () {
double numbers[] = {3.141516, 1.01, 200.78901, 0.12345};
int len = sizeof(numbers) / sizeof(numbers[0]);
std::cout << std::setprecision(4);
for (int i = 0; i < len; ++i) {
std::cout << numbers[i] << '\n';
}
return 0;
}
outputs:
3.142
1.01
200.8
0.1235
But what I want is: (at most 4 digits after decimal point without trailing zeros)
3.1415
1.01
200.789
0.1235
Is iomanip capable of doing this? Without using other tricks (like round)?
EDIT
It seems that I haven't made it clear enough. My question is iomanip specific
All I want to know is whether iomanip is capable of doing things I've described because iomanip is said to be the standard library for input/output manipulators. The posted question is
Is iomanip capable of doing this?
It's more like "is it supported" rather than "give me any solution".
I have searched it again, looked up iomanip references hoping for a clean and compact way to format floating numbers for at most n digits, using unnecessary libraries as little as possible.
And there seems to be no standard way to achieve this.
One (ugly) option to obtain OP's desired output is to represent the number with the wanted maximum precision and then just remove the unwanted zeroes:
#include <iostream>
#include <iomanip>
#include <sstream>
#include <vector>
int main()
{
std::vector<double> numbers {
3.141516, 1.01, 200.78901, 0.12345, 9.99999
};
for (auto x : numbers)
{
// "print" the number
std::stringstream ss;
ss << std::fixed << std::setprecision(4) << x;
// remove the unwanted zeroes
std::string result{ss.str()};
while (result.back() == '0')
result.pop_back();
// remove the separator if needed
if (result.back() == '.')
result.pop_back();
std::cout << result << '\n';
}
std::cout << "\nJustified:\n";
for (auto x : numbers)
{
// "print" the number
std::stringstream ss;
ss << std::fixed << std::setprecision(4) << std::setw(15) << x;
// remove the unwanted zeroes
std::string result{ss.str()};
auto it = result.rbegin();
while (*it == '0')
*it++ = ' ';
// remove the separator if needed
if (*it == '.')
*it = ' ';
std::cout << result << '\n';
}
}
Live example: https://ideone.com/8zP17O
So:
in std::fixedfield mode, std::setprecision sets the maximum number of significant figures, not decimal places;
if you flip to std::fixed it means exact number of decimal places;
C++ does not provide any analogue to the %.Nf printf format string! (up to N decimal places)
I've just thrown together a little fake I/O manipulator that can get the behaviour we both want. It's not terribly performant, but it does the job:
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <cstdio>
struct sprintf_wrapper
{
sprintf_wrapper(std::string fmt_str)
: _fmt_str(std::move(fmt_str))
{}
struct proxy
{
proxy(const sprintf_wrapper& wrapper, std::ostream& os)
: _wrapper(wrapper)
, _os(os)
{}
std::ostream& Resolve(const double value) const
{
// First find out how many characters we're going to need
const int len = std::snprintf(nullptr, 0, _wrapper._fmt_str.c_str(), value);
if (len < 0)
{
_os.setstate(std::ios::failbit);
return _os;
}
// Then allocate a buffer
std::string result;
result.resize(len);
// Actually serialise the value according to the format string
if (std::sprintf(result.data(), _wrapper._fmt_str.c_str(), value) < 0)
{
_os.setstate(std::ios::failbit);
return _os;
}
// Stream it out
_os.write(result.data(), result.size());
return _os;
}
friend std::ostream& operator<<(const proxy& obj, const double val)
{
return obj.Resolve(val);
}
private:
const sprintf_wrapper& _wrapper;
std::ostream& _os;
};
friend proxy operator<<(std::ostream& os, const sprintf_wrapper& obj)
{
return proxy(obj, os);
}
private:
std::string _fmt_str;
};
inline auto sprintf_f(size_t n, const bool showpos = false)
{
std::stringstream fmt;
fmt << '%';
if (showpos) fmt << '+';
fmt << '.' << n << 'f';
return sprintf_wrapper(fmt.str());
}
int main()
{
std::cout << sprintf_f(2) << 4.123456789 << '\n';
std::cout << sprintf_f(3) << 4.123456789 << '\n';
std::cout << sprintf_f(4) << 4.123456789 << '\n';
std::cout << sprintf_f(5) << 4.123456789 << '\n';
std::cout << sprintf_f(6) << 4.123456789 << '\n';
}
(live demo)
Use a combination of std::fixed and std::setprecision.
#include <iomanip>
#include <iostream>
int main() {
double d = 311.3456;
std::cout << std::fixed;
std::cout << std::setprecision(4);
std::cout << d << std::endl;
}

Convert string to double using custom numpunct doesn't work as expected

I am trying to convert a string to a double using a custom numpunct. I want the conversion to fail if the string is not in a currency-style format - e.g. 1,000,000.0
#include <iostream>
#include <sstream>
using namespace std;
class ThousandCommaSeparator: public std::numpunct<char>
{
public:
ThousandCommaSeparator(){}
protected:
virtual char do_decimal_point() const { return '.'; }
virtual char do_thousands_sep() const { return ','; }
virtual string_type do_grouping() const { return "\3";}
};
int main()
{
istringstream ss("2015/05/03");
ss.imbue(locale(cout.getloc(),new ThousandCommaSeparator));
double output;
if (ss >> output)
{
cout << "Success: " << output << endl;
}
else
{
cout << "Failure: " << output << endl;
}
}
I want the above to fail, but it always succeeds, and sets the value of output to 2015. I'm guessing I'm using numpunct incorrectly, hopefully someone can point me in the right direction!
Thousands separators in an input stream are optional. If they are present, they must be placed correctly, but they don't have to be present.
Thus, 2015 is a valid input to convert to an number regardless of std::numpunct.

C++ how to avoid trailing zeroes?

If you do
double number;
cout.precision(3)
cout<<number;
for a number like 1.23456 you get 1.234 but if the number is 1.2 you get 1.200. How to get both 1.234 and 1.2 (they are useless zeroes)? Suppose you don't know what number you have to print.
#include <iostream>
#include <iomanip>
using namespace std;
auto main() -> int
{
cout << setprecision( 4 );
cout << 1.23456 << endl; // -> "1.235"
cout << 1.2 << endl; // -> "1.2"
}
It's that simple: it's what you get by default.
C++03 lacked a manipulator for resetting to default formatting after setting fixed or scientific. However, in C++11 the defaultfloat manipulator was introduced. You can use it like this:
#include <iostream> // defaultfloat
#include <iomanip> // setprecision
using namespace std;
#ifdef __GNUC__ // Also check for version number, e.g. 4.8.2 and earlier
namespace std {
inline
auto defaultfloat( ios_base& stream )
-> ios_base&
{ stream.unsetf( ios_base::floatfield ); return stream; }
}
#endif
auto main() -> int
{
cout << "Lots of digits: " << fixed << setprecision( 16 ) << 1.2 << endl;
cout << endl;
cout << "Deault presentation:" << endl;
cout << defaultfloat;
cout << 1.234 << endl;
cout << 1.2 << endl;
}
Did you even try your own example?
Trailing zeroés are NOT printed (by default).
In fact, one usually wants (!) those zeroes (they convey information and they avoid clobbering up the output).
This is achieved by cout << std::fixed.
Unless you have used std::fixed, 1.2 will produce 1.2, NOT 1.200, even with precision higher than 2.
BTW: Precision means all digits, not just those after the dot, hence precision=3 leads to 1.23 - UNLESS you go std::fixed, then only those after the dot are counted.
You might write a manipulator to achieve your formatting:
#include <cmath>
#include <iostream>
template <typename T>
struct DecimalPrecision
{
const T& value;
const unsigned decimals;
DecimalPrecision(const T& value, unsigned decimals)
: value(value), decimals(decimals)
{}
void write(std::ostream& stream) const {
std::ios_base::fmtflags flags = stream.flags();
stream.unsetf(std::ios_base::floatfield);
std::streamsize restore
= stream.precision(std::ceil(std::log10(std::abs(value))) + decimals);
stream << value;
stream.precision(restore);
stream.flags(flags);
}
};
template <typename T>
inline DecimalPrecision<T> decimal_precision(const T& value, unsigned decimals) {
return DecimalPrecision<T>(value, decimals);
}
template <typename T>
inline std::ostream& operator << (std::ostream& stream, const DecimalPrecision<T>& value) {
value.write(stream);
return stream;
}
#include <iomanip>
int main()
{
std::cout << std::setprecision(2);
double values[] = { 12345.6789, 1.23456789, 1.2 };
for(unsigned i = 0; i < sizeof(values)/sizeof(values[0]); ++i)
std::cout
<< i << ": " << values[i] << '\n'
<< " " << decimal_precision(values[i], 2) << '\n';
}

how to format out in c++?

I know how to use printf() to format output of float, for example:
float i = 1;
printf("%.2f", i);
but how to format the output using cout to output 2 digits after "."?
Following will do:
std::cout<<std::fixed<<std::setprecision(2)<<i;
You will also need to include iomanip
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
cout << setprecision(2) << setiosflags(ios::fixed) << 3.141592 << endl;
}
use setprecision().
A red herring is to use std::setprecision on its own:
float f = 3.1415;
std::cout << std::setprecision(2) << f;
However, "precision" is not the same as "number of decimal places", as shown in this example.
Fortunately, and somewhat confusingly, switching the stream to "fixed-point" display changes the meaning of std::setprecision to something more akin to "setDecimalPlaces".
So, you can write this:
float f = 3.1415;
std::cout << std::fixed << std::setprecision(2) << f;
Boost format helps:
std::cout << boost::format("%.2f") % i;
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double x = 800000.0/81.0;
cout << setiosflags(ios::fixed) << setprecision(2) << x;
return 0;
}
hope this helps.........
#include <iostream>
#include <iomanip>
using namespace std;
int main () {
double f =3.14159;
cout << setprecision (5) << f << endl;
cout << setprecision (9) << f << endl;
cout << fixed;
cout << setprecision (5) << f << endl;
cout << setprecision (9) << f << endl;
return 0;
}
output..
> 3.1416
> 3.14159
> 3.14159
> 3.141590000
cout << ffmt(0, 2) << i;
Where ffmt is defined as:
class ffmt
{
int width;
int precision;
public:
ffmt( int width, int precision )
: width( width )
, precision( precision )
{
}
friend std::ostream& operator<<(
std::ostream& dest,
ffmt const& manip )
{
dest.setf( std::ios_base::fixed, std::ios_base::floatfield );
dest.width( width );
dest.precision( precision );
}
};
You can also extend this to restore format state at the end of the full
expression; it's not too important for floating point, because most of
the time, you'll use the manipulator in front of each output, but a
manipulator which leaves the stream outputting hex is likely to lead to
surprising output later.
As a general rule, except for quicky demo or test programs, you almost
never use the standard manipulators, other that std::setw. For that
matter, in a lot of applications, you'll even avoid things like ffmt,
in favor of specific manipulators for each semantic value you have.