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;
}
Related
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.
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.
While working on a fairly large project, I happened to notice that one of my functions that is supposed to return a Long value is either returning an Integer. I reproduced the error in a very small environment thinking that it would make the problem clear to me, but I'm still not seeing the issue. The input is 1.123, and the return value is 1. If I input any Long, for example; 123.456, it will only return 123. What am I not seeing?
Source1.cpp
#ifndef HEADER_H
#define HEADER_H
using namespace std;
class testClass
{
private:
long m_testLong = 0.0;
public:
long getTestLong();
void setTestLong(long sn);
};
#endif
Header.h
#include "Source1.cpp"
#include <string.h>
void testClass::setTestLong(long sn)
{
m_testLong = sn;
}
long testClass::getTestLong()
{
return m_testLong;
}
Source.cpp
#include <iostream>
#include "Source1.cpp"
#include "Header.h"
using namespace std;
int main(void)
{
testClass *myClass = new testClass;
cout << "Setting test long value using setTestLong function -- 1.123" << endl;
myClass->setTestLong(1.123);
long tempTestLong = 0.0;
tempTestLong = myClass->getTestLong();
cout << tempTestLong << endl;
system("Pause");
return 0;
}
OK, so the answer was painfully simple. I hadn't worked with longs before, but I thought I knew what they were. I didn't.
So longs and integers both are whole numbers, and having the type listed as long made me assume an integer wouldn't work, and I tested the function with a double because of my misunderstanding. Thanks for the help!
The long and int types are integral types, they can only hold whole numbers like 7 or 42.
You should be using float or double as a type, preferably the latter for increased range and precision. That will allow you to hold real numbers such as 3.141592653589 or 2.718281828459.
Long is an integer. Assigning a floating point value to integer causes rounding.
You want double or float.
Getting input from another source; which populates a string of up to 2048 characters.
What is the most efficient way of populating and comparing this string? - I want to be able to easily append to the string also.
Here are three attempts of mine:
C-style version
#include <cstdio>
#include <cstring>
int main(void) {
char foo[2048];
foo[0]='a', foo[1]='b', foo[2]='c', foo[3]='\0'; // E.g.: taken from u-input
puts(strcmp(foo, "bar")? "false": "true");
}
C++-style version 0
#include <iostream>
int main() {
std::string foo;
foo.reserve(2048);
foo += "abc"; // E.g.: taken from user-input
std::cout << std::boolalpha << (foo=="bar");
}
C++-style version 1
#include <iostream>
int main() {
std::string foo;
foo += "abc"; // E.g.: taken from user-input
std::cout << std::boolalpha << (foo=="bar");
}
What is most efficient depends on what you optimize for.
Some common criteria:
Program Speed
Program Size
Working Set Size
Code Size
Programmer Time
Safety
Undoubted King for 1 and 2, in your example probably also 3, is C style.
For 4 and 5, C++ style 1.
Point 6 is probably with C++-style.
Still, the proper mix of emphasizing these goal is called for, which imho favors C++ option 0.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main() {
string x;
getline(cin,x);
ofstream o("f:/demo.txt");
o.write( (char*)&x , sizeof(x) );
}
I get the unexpected output.I don't get what i write in a string function.
Why is this ?
Please explain .
Like when i write steve pro i get the output as 8/ steve pro ÌÌÌÌÌÌ ÌÌÌÌ in the file
I expect that the output be steve pro
You are treating an std::string like something that it is not. It's a complex object that, somewhere in its internals, stores characters for you.
There is no reason to assume that a character array is at the start of the object (&x), and the sizeof the object has no relation to how many characters it may indirectly hold/represent.
You're probably looking for:
o.write(x.c_str(), x.length());
Or just use the built-in formatted I/O mechanism:
o << x;
You seem to have an incorrect model of sizeof, so let me try to get it right.
For any given object x of type T, the expression sizeof(x) is a compile-time constant. C++ will never actually inspect the object x at runtime. The compiler knows that x is of type T, so you can imagine it silently transforming sizeof(x) to sizeof(T), if you will.
#include <string>
int main()
{
std::string a = "hello";
std::string b = "Stack Overflow is for professional and enthusiast programmers, people who write code because they love it.";
std::cout << sizeof(a) << std::endl; // this prints 4 on my system
std::cout << sizeof(b) << std::endl; // this also prints 4 on my system
}
All C++ objects of the same type take up the exact amount of memory. Of course, since strings have vastly different lengths, they will internally store a pointer to a heap-allocated block of memory. But this does not concern sizeof. It couldn't, because as I said, sizeof operates at compile-time.
You get exactly what you write: the binary raw value of a pointer to char...
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string x;
getline(cin,x);
ofstream o("tester.txt");
o << x;
o.close();
}
If you insist on writing a buffer directly, you can use
o.write(x.c_str(), x.size());
PS A little attention to code formatting unclouds the mind
You're passing the object's address to write into the file, whereas the original content lies somewhere else, pointed to by one of its internal pointers.
Try this:
string x;
getline(cin,x);
ofstream o("D:/tester.txt");
o << x;
// or
// o.write( x.c_str() , x.length());