std::ostream, truncate instead of rounding for floating-point numbers - c++

I have my own io-manipulator that prepares a std::ostream stream to print floating-point numbers:
#include <iostream>
#include <iomanip>
inline std::ostream& my_fmt(std::ostream& os)
{ return os << std::fixed << std::setprecision(2); }
int main()
{
std::cout << my_fmt << 3.146; // It prints 3.15
}
I wonder how could I change my io-manipulator to force a truncation by the specified number of decimals instead of a rounding, which is the default behaviour of std::num_put<CharT>::do_put.
For example, in my snippet, I want the program prints 3.14 instead of 3.15.
I guess that the answer must be creating my own locale or a facet or something and reimplement the put function, by inheritance or by a partial specialization of std::num_put, but I'm not sure about how the IO-library and locale/facets works together and I don't know exactly what I have to do or what is what I need to specialize or reimplement.

Related

Printing float and double values using cout in C++

For the following code:
#include <iostream>
using namespace std;
class Hall
{
public:
double cost;
};
int main()
{
Hall hall;
hall.cost=10000.50;
cout<<hall.cost;
return 0;
}
Why does this code output 10000.5 and not 10000.50, can someone explain the logic behind this?
can someone explain the logic behind this?
The default behaviour is not show any trailing zeroes.
double (and floating-point variables in general) don't store a specific spelling of the number (base-10 or otherwise). That would be way too inefficient, and the ability to store meaningless zeroes would waste memory.
Instead, the numbers are encoded in a certain binary format. Printing them reproduces the base-10 spelling from binary.
By default, C++ does not display trailing zeros, however the standard library <iomanip> can be used along with std::fixed from <iostream>. Here is an example:
#include <iostream>
#include <iomanip>
int main() {
double myVar = 123.4;
std::cout << std::fixed << std::setprecision(2); // 2 trailing digits
std::cout << myVar << std::endl;
return 0;
}

Define multiprecision pi in boost:multiprecision

I need pi (3.1415...) in arbitrary (but fixed) precision in boost::multiprecision.
The constants in boost::math::constants are only defined up to a fixed number of digits, as pointed out in this answer, so I need to compute it by myself.
Because I'm using this number often and with a very large number of digits, I would like to compute it in runtime only once. what would be a simple yet fast way to have it?
I thought using
typedef number<cpp_dec_float<PRECISION> > mpfloat; // PRECISION is compile time.
const int PI = atan(mpfloat(1))*4;
but I'm not sure this is a common idiom for it.
In c++14 you can use a template variable (http://en.cppreference.com/w/cpp/language/variable_template).
Note that you can already have what you want by including
#include <boost/multiprecision/detail/default_ops.hpp>
That header ends up including constants.hpp which defines template <class T> const T& get_constant_pi().
This is the c++03 idiom for template variables already (as it stores a function-local static result value).
calc_pi has the first 1100 digits hardcoded, and the rest is calculated via optimized formulae if required.
Demo with 50 and 5000 digits:
Live On Coliru (c++14)
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/detail/default_ops.hpp>
#include <boost/multiprecision/number.hpp>
#include <iostream>
namespace {
namespace bmp = boost::multiprecision;
template <int N> bmp::number<bmp::cpp_dec_float<N> > const my_const_pi
= bmp::default_ops::get_constant_pi<bmp::cpp_dec_float<N> >();
}
int main() {
std::cout << std::setprecision(50) << my_const_pi<50> << "\n";
std::cout << std::setprecision(5000) << my_const_pi<5000> << "\n";
}
Prints
3.1415926535897932384626433832795028841971693993751
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275900994657640789512694683983525957098258226205224894077267194782684826014769909026401363944374553050682034962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382686838689427741559918559252459539594310499725246808459872736446958486538367362226260991246080512438843904512441365497627807977156914359977001296160894416948685558484063534220722258284886481584560285060168427394522674676788952521385225499546667278239864565961163548862305774564980355936345681743241125150760694794510965960940252288797108931456691368672287489405601015033086179286809208747609178249385890097149096759852613655497818931297848216829989487226588048575640142704775551323796414515237462343645428584447952658678210511413547357395231134271661021359695362314429524849371871101457654035902799344037420073105785390621983874478084784896833214457138687519435064302184531910484810053706146806749192781911979399520614196634287544406437451237181921799983910159195618146751426912397489409071864942319615679452080951465502252316038819301420937621378559566389377870830390697920773467221825625996615014215030680384477345492026054146659252014974428507325186660021324340881907104863317346496514539057962685610055081066587969981635747363840525714591028970641401109712062804390397595156771577004203378699360072305587631763594218731251471205329281918261861258673215791984148488291644706095752706957220917567116722910981690915280173506712748583222871835209353965725121083579151369882091444210067510334671103141267111369908658516398315019701651511685171437657618351556508849099898599823873455283316355076479185358932261854896321329330898570642046752590709154814165498594616371802709819943099244889575712828905923233260972997120844335732654893823911932597463667305836041428138830320382490375898524374417029132765618093773444030707469211201913020330380197621101100449293215160842444859637669838952286847831235526582131449576857262433441893039686426243410773226978028073189154411010446823252716201052652272111660396665573092547110557853763466820653109896526918620564769312570586356620185581007293606598764861179104533488503461136576867532494416680396265797877185560845529654126654085306143444318586769751456614068007002378776591344017127494704205622305389945613140711270004078547332699390814546646458807972708266830634328587856983052358089330657574067954571637752542021149557615814002501262285941302164715509792592309907965473761255176567513575178296664547791745011299614890304639947132962107340437518957359614589019389713111790429782856475032031986915140287080859904801094121472213179476477726224142548545403321571853061422881375850430633217518297986622371721591607716692547487389866549494501146540628433663937900397692656721463853067360965712091807638327166416274888800786925602902284721040317211860820419000422966171196377921337575114959501566049631862947265473642523081770367515906735023507283540567040386743513622224771589150495309844489333096340878076932599397805419341447377441842631298608099888687413260472
I'd recommend just putting the value of pi into your source code as a constant with however many digits you need.
Define it as a static within a struct.

cout skipping the numbers after the decimal spaces

I have assigned an integer to a double variable, but cout prints the double variable as an int. not as double . If I introduce cout << showpoint; in the code then I m able to see the decimal values at the out put . Why is it so in the first case ? Here is the code .
#include <iostream>
using namespace std;
template <class T>
T sum(T a,T b)
{
T retval;
retval=a+b;
return retval;
}
int main()
{
double a,x;
float y,v=4.66;
int z(3);
x=z;
y=(double)z;
a=sum(5,6);
//cout << showpoint;
cout<<"The value of a is : "<<a<<endl;
cout<<"The value of x is : "<<x<<endl;
cout<<"The value of y is : "<<y<<endl;
}
The output in first case is
The value of a is : 11
The value of x is : 3
The value of y is : 3
The output after enabling cout<<showpoint in the second case is
The value of a is : 11.0000
The value of x is : 3.00000
The value of y is : 3.00000
By default, floating point types are only displayed with a decimal point if they need one. If they have an integer value, they are displayed without one.
As you found, you can change this behaviour with showpoint (and change it back with noshowpoint), if you want.
The answer seems to be in the same link posted by you. Just that cpp standards (i mean std streams) have the printing of trailing zeros disabled by default.
The fundamental reason is only because that's what the standard
says. For historical reasons, C++ output formatting is defined
in terms of C and printf formatting. By default, floating
point is output using the %g format, which is an adaptive
format, which changes according to the values involved, as well
as according to various formatting flags. For similar
historical reasons: the default format will suppress trailing
zeros after the point, and if there are no digits after the
point, it will suppress the point as well. If you specify
showpoint, the results are the equivalent of %#g, which not
only causes the point to be displayed, regardless, but also
causes trailing zeros to be displayed.
In practice, this default format is almost never what you want
for real program output; its only real use is for debugging, and
various "informational" output. If you want fixed point, with
a fixed number of decimals after the point, you have to specify
it:
std::cout.setf( std::ios_base::fixed, std::ios_base::floatfield );
Normally, this will be done in some sort of hand written
manipulator, so that the format for a specific semantic value is
specified once (in the manipulator), and then you use the
manipulator to specify the signification of the value to be
output, something like:
std::cout << weight << someWeight;
For quick, throw away code, it's often convenient to have some
sort of generic specifiers as well; I've got something like:
class FFmt
{
int myWidth;
int myPrecision;
public:
FFmt( int width, int precision = 6 )
: myWidth( width )
, myPrecision( precision )
{
}
friend std::ostream& operator<<( std::ostream& dest, FFmt const& fmt )
{
dest.setf( std::ios_base::fixed, std::ios_base::floatfield );
dest.precision( myPrecision );
dest.setw( myWidth );
return dest;
}
};
(Actually, my version is more complex, because it derives from
a base class which saves the current formatting options in the
<< operator, and restores them in the destructor; since such
classes are used almost exclusively as temporaries, this means
at the end of the full expression.)
This supports writing things like:
std::cout << FFmt( 9, 6 ) << x;
Not something you'd want in production code (since you don't want to
specify the format at the point you're outputting the data), but
quite useful for quick, one time programs.

C++ type converting issue

Consider following code:
#include <iostream>
using namespace std;
int aaa(int a) {
cout << a * 0.3 << endl;
return a * 0.3;
}
int main()
{
cout << aaa(35000);
}
It prints out:
10500
10499
Why output differs?
I have a workaround to use "return a * 3 / 10;" but I don't like it.
Edit:
Found that doing "return float(a * 0.3);" gives expected value;
The result of 0.3*35000 is a floating point number, just slightly less than 10500. When printed it is rounded to 10500, but when coerced into an int the fractional digits are discarded, resulting in 10499.
int * double expression yields double, that's what the first thing prints.
Then you convert to int chopping the remaining part (even if it's almost there, sitting at 10500-DBL_EPSILON), and pass that back. The second prints that value.
float-int conversions should be made with care, better not at all.
a * 0.3 has type double. The call inside aaa calls
ostream& operator<< (double val);
whereas the one outside calls
ostream& operator<< (int val);
You'd get a warning (if you turn them on - I suggest you do) that the implicit cast from double to int isn't recommended.

Why compiler warns about implicit conversion in setprecision?

When I compile the following code, compiler gives me the warning:
"Implicit conversion loses integer precision: 'std::streamsize' (aka 'long') to 'int'".
I'm a little bit confused about this warning since I just try to save the current value of the precision to set it back to the original value later.
#include <iomanip>
#include <iostream>
int main() {
std::streamsize prec = std::cout.precision();
std::cout << std::setprecision(prec);
}
What is the right way to save the precision value and set it back later in this case?
It looks like it's just an oversight in the standard specification.
ios_base::precision has two overloads, one that gets and one that sets the precision:
// returns current precision
streamsize precision() const;
// sets current precision and returns old value
streamsize precision(streamsize prec) const;
So this code will not give you warnings:
#include <iostream>
int main() {
std::streamsize prec = std::cout.precision(); // gets
std::cout.precision(prec); // sets
}
However, the setprecision() function simply takes a plain old int:
unspecified-type setprecision(int n);
and returns an unspecified functor, which when consumed by a stream str has the effect of:
str.precision(n);
In your case, streamsize is not an int (and does not have to be), hence the warning. The standard should probably be changed so that setprecision's parameter is not int, but streamsize.
You can either just call precison() yourself, as above, or assume int is sufficient and cast.
#include <iomanip>
#include <iostream>
int main() {
std::streamsize prec = std::cout.precision();
std::cout << std::setprecision(static_cast<int>(prec));
}
Edit: Apparently it was submitted to be fixed and reached no concensus (closed as not-a-defect).