In a C++ code I have a matrix of double variables which I print out. However because all of them have different number of digits, the output format is destroyed. One solution is to do
cout.precision(5) but I want different columns have a different precision. Also, because there are negative values in some cases, the presence of the - sign also causes problems. How to get around this and produce a properly formatted output?
Off the top of my head, you can use setw(int) to specify the width of the output.
like this:
std::cout << std::setw(5) << 0.2 << std::setw(10) << 123456 << std::endl;
std::cout << std::setw(5) << 0.12 << std::setw(10) << 123456789 << std::endl;
gives this:
0.2 123456
0.12 123456789
The key is, as others have said, to use manipulators. What they
neglected to say is that you normally use manipulators that you write
yourself. An FFmt manipulator (which corresponds to the F format in
Fortran is fairly easy:
class FFmt
{
int myWidth;
int myPrecision;
public:
FFmt( int width, int precision )
: myWidth( width )
, myPrecision( precision )
{
}
friend std::ostream&
operator<<( std::ostream& dest, FFmt const& fmt )
{
dest.setf( std::ios_base::fixed, std::ios_base::formatfield );
dest.precision( myPrecision );
dest.width( myWidth );
return dest;
}
};
This way, you can define a variable for each column, say:
FFmt col1( 8, 2 );
FFmt col2( 6, 3 );
// ...
and write:
std::cout << col1 << value1
<< ' ' << col2 << value2...
In general, except in the simplest programs, you should probably not be
using the standard manipulators, but rather custom manipulators based on
your application; e.g. temperature and pressure if that's the sort of
thing your dealing with. In this way, it's clear in the code what
you're formatting, and if the client suddenly asks for one more digit in
the pressure, you know exactly where to make the change.
Use manipulators.
From sample here:
#include <iostream>
#include <iomanip>
#include <locale>
int main()
{
std::cout.imbue(std::locale("en_US.utf8"));
std::cout << "Left fill:\n" << std::left << std::setfill('*')
<< std::setw(12) << -1.23 << '\n'
<< std::setw(12) << std::hex << std::showbase << 42 << '\n'
<< std::setw(12) << std::put_money(123, true) << "\n\n";
std::cout << "Internal fill:\n" << std::internal
<< std::setw(12) << -1.23 << '\n'
<< std::setw(12) << 42 << '\n'
<< std::setw(12) << std::put_money(123, true) << "\n\n";
std::cout << "Right fill:\n" << std::right
<< std::setw(12) << -1.23 << '\n'
<< std::setw(12) << 42 << '\n'
<< std::setw(12) << std::put_money(123, true) << '\n';
}
Output:
Left fill:
-1.23*******
0x2a********
USD *1.23***
Internal fill:
-*******1.23
0x********2a
USD ****1.23
Right fill:
*******-1.23
********0x2a
***USD *1.23
Take a look at stream manipulators, especially std::setw and std::setfill.
float f = 3.1415926535;
std::cout << std::setprecision(5) // precision of floating point output
<< std::setfill(' ') // character used to fill the column
<< std::setw(20) // width of column
<< f << '\n'; // your number
Try using setw manipulator. Please refer http://www.cplusplus.com/reference/iostream/manipulators/setw/ for further information
There is a way using i/o manipulators, but I find it unwieldy. I would just write a function like this:
template<typename T>
std::string RightAligned(int size, const T & val)
{
std::string x = boost::lexical_cast<std::string>(val);
if (x.size() < size)
x = std::string(size - x.size(), ' ') + x;
return x;
}
Related
This example program was created with the sole purpose of showing what setprecision and setw does. I dont understand the purpose of the third line that says "setprecision(5)". I commented the line out to see the difference but it looks the exact same. Is there no purpose?
cout << "\nSales Figures\n";
cout << "-------------\n";
cout << setprecision(5);
cout << "Day 1: " << setw(8) << day1 << endl;
cout << "Day 2: " << setw(8) << day2 << endl;
cout << "Day 3: " << setw(8) << day3 << endl;
cout << "Total: " << setw(8) << total << endl;
The setprecision() function is part of the "iomanip" library and is used when you need to output a float to a certain number of decimal places. This is good for displaying money amounts and other things that typically are shown with a set number of digits after the decimal point (even if those digits are 0).
Say you have a float called price: If you stored 10.0 in that float, C++ would not know how many decimal points to output when you print into the screen; setprecision(2) would make the output 10.00.
You can find the documentation at this link: https://cplusplus.com/reference/iomanip/setprecision/.
It includes the following code as an example of how setprecision() works.
// setprecision example
#include <iostream> // std::cout, std::fixed
#include <iomanip> // std::setprecision
int main () {
double f =3.14159;
std::cout << std::setprecision(5) << f << '\n'; // This outputs 3.1415
std::cout << std::setprecision(9) << f << '\n'; // This outputs 3.14159
std::cout << std::fixed;
std::cout << std::setprecision(5) << f << '\n'; // This outputs 3.14159
std::cout << std::setprecision(9) << f << '\n'; // This outputs 3.141590000
return 0;
}
Note that setprecision() is only applicable to data types with decimal points such as floats and doubles.
How would I modify code, like the code shown below, to exclude the constant VALUE_1 when using setprecision(2) so that it will display 3 decimals instead of 2 like the others?
#include <iostream>
#include <iomanip>
using namespace std;
const double VALUE_1 = .011;
int main(void)
{
double value2;
double value3;
value2 = 2.362;
value3 = 5;
cout << fixed << setprecision(2);
cout << value2 << endl;
cout << VALUE_1 << endl;
cout << value3 << endl;
return 0;
}
I tried the following fix and it works fine, but is there anything else that doesn't look so improvised? Or is this the intended method?
cout << value_2 << endl;
cout << setprecision (3) << value_1 << endl;
cout << setprecision (2) << value_3 << endl;
I would probably do it by writing my own manipulator to at least combine the steps of setting fixed format and the width I wanted:
class fixed {
int width;
public:
fixed(int width) : width(width) {}
friend std::ostream &operator<<(std::ostream &os, fixed const &f) {
return os << std::fixed << std::setw(width);
}
};
Then you'd write out your numbers like:
std::cout << fixed(3) << value2 << '\n'
<< fixed(2) << VALUE_1 << '\n'
<< fixed(2) << value3 << '\n';
Admittedly, not a drastic improvement, but seems at least a little better to me.
Oh and avoid std::endl unless you really need it (which is pretty much never).
I am new to C++ STL libraries and need help.
I want to add two numbers suppose A = 4555 and B = 50, and output them as:
4555
+50
4605
Another Examples:
500000 + 12
500000
+12
500012
If i am storing both A and B in integer data type while the sign '+' in character data type. How can i manipulate them to get the preferred output.
I just cant figure out how to manipulate two variables together.
You might utilize the manipulators std::showpos, std::noshowpos and std::setw:
#include <iostream>
#include <iomanip>
int main() {
int a = 4555;
int b = 50;
std::cout
<< std::noshowpos << std::setw(10) << a << '\n'
<< std::showpos << std::setw(10) << b << '\n'
<< std::noshowpos << std::setw(10) << (a+b) << '\n';
}
If you want a width depending on the values you may use three std::ostringstream(s) and create intermediate strings (without setw). After that you print the strings using the maximal length of each for setw:
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <sstream>
int main() {
int a = 4555;
int b = 50;
std::ostringstream as;
std::ostringstream bs;
std::ostringstream rs;
as << std::noshowpos << a;
bs << std::showpos << b;
rs << std::noshowpos << (a+b);
unsigned width = std::max({ as.str().size(), bs.str().size(), rs.str().size() });
std::cout
<< std::setw(width) << as.str() << '\n'
<< std::setw(width) << bs.str() << '\n'
<< std::setw(width) << rs.str() << '\n';
}
See also:
http://www.cplusplus.com/reference/iomanip/
http://www.cplusplus.com/reference/ios/
Note: You may have a look at the manipulator std::internal.
If you could use constant width (or variable width equal to the maximum width of the numbers involved) with std::setw from <iomanip> as:
#include <iostream>
#include <iomanip>
#include <string>
void display_sum(int a, int b)
{
std::cout << std::setw(10) << a << "\n"
<< std::setw(10) << ("+" + std::to_string(b)) << "\n"
<< std::setw(10) << (a+b) <<"\n" << std::endl;
}
int main()
{
display_sum(4555, 50);
display_sum(500000, 12);
display_sum(503930, 3922);
}
Output:
4555
+50
4605
500000
+12
500012
503930
+3922
507852
Online demo
In your example the fields can fit a maximum number of 7 characters. Perhaps you want to resize the strings to 7 before writing. e.g. fname.resize(7).
To format it as you want you need to #include <iomanip> and use std::left and std::setw(7).
file1 << left << setw(7) << fname
<< tab << setw(7) << lname
<< tab << setw(7) << street
<< tab << setw(7) << city
<< tab << setw(7) << state
<< tab << setw(7) << zip << endl;
I am working on a C++ program with a lot of numbers that are type double (values in the millions and billions with just a couple places to the right of the decimal point). I am performing calculations on these numbers and then printing the result to text/CSV files. I noticed that in the text files, all of my numbers appear to be rounded (to six digits). So, a value of 13,169,911 is showing up as 13,169,900 in my output file.
Is this rounding only occuring on the print? In order to get the full number of digits in the variable, do I just need to specify something when I write to a file? I included a sample of my write to file code below:
void PrintPropFinance(vector<PropFinance>& PF, int NumProps, int Iterations, int ForecastLength,
string CurDeal, string ModelRunID, string ScenName, Assumptions& Ass) {
string filename;
ofstream OutFile;
ostringstream s1;
s1 << BASEPATH << "Output/" << CurDeal << "_" << ModelRunID << "_" <<
ScenName << "_PropFinance" << ".csv";
filename = s1.str();
OutFile.open(filename);
// Put in the column headers first
OutFile << "PropID" << ","
<< "Item" << ","
<< "StartDate" << ","
<< "NumOfPeriod" << ","
<< "Result" << ","
<< "Isap" << ","
<< "CurLoanBal" << ","
for (int i=1; i<=NumProps; ++i) {
// Populate the single-vector variables
OutFile << PF[i].PropID << ","
<< PF[i].Item << ","
<< PF[i].StartDate << ","
<< PF[i].NumOfPeriod << ","
<< PF[i].Result << ","
<< PF[i].Isap << ","
<< PF[i].CurLoanBal << ","
<< endl;
}
OutFile.close();
}
// Prop finance class definition
class PropFinance {
public:
string PropID;
int Item;
string StartDate;
int NumOfPeriod;
string Isap;
double CurLoanBal;
}
The problem is likely to do with the way the output stream produces the output for doubles: if 13169911 gets printed in "scientific notation", it would look like 1.31699E7. Excel will read this notation just fine, but would put zeros for the digits it does not "see", making the number look like 13,169,900.
To fix this problem, add fixed manipulator when you output your double to ensure that all digits get printed:
OutFile << PF[i].PropID << ","
<< PF[i].Item << ","
<< PF[i].StartDate << ","
<< PF[i].NumOfPeriod << ","
<< fixed << PF[i].Result << ","
<< PF[i].Isap << ","
<< fixed << PF[i].CurLoanBal << ","
<< endl;
You need to use std::setprecision to increase the precision of the stream. By default an iostream has only 6 digits of precision.
Try this:
OutFile << std::setprecision(std::numeric_limits<long double>::digits10 << PF[i].CurLoanBal;
Bear in mind that this will affect all subsequent operations on the stream. To be honest though, that's probably what you want!
As comparison between std::setprecision and std::fixed, this program:
#include <iostream>
#include <iomanip>
#include <cmath>
#include <limits>
int main()
{
const long double test_value = 13169911.7777777;
std::cout << "default precision (6): " << test_value << '\n'
<< "std::fixed: " << std::fixed << test_value << '\n'
<< "std::precision(10): " << std::defaultfloat << std::setprecision(10) << test_value << '\n'
<< "std::precision(10) & std::fixed: " << std::fixed << std::setprecision(10) << test_value << '\n'
<< "max precision: " << std::defaultfloat << std::setprecision(std::numeric_limits<long double>::digits10) << test_value << '\n'
<< "max precision & std::fixed: " << std::fixed << std::setprecision(std::numeric_limits<long double>::digits10) << test_value << '\n'
;
}
Produces this output:
default precision (6): 1.31699e+007
std::fixed: 13169911.777778
std::precision(10): 13169911.78
std::precision(10) & std::fixed: 13169911.7777777000
max precision: 13169911.7777777
max precision & std::fixed: 13169911.777777700000000
So I think you may want std::setprecision rather than std::fixed. Though I imagine that you'll only have two decimal places anyway so perhaps it doesn't matter.
Read more here: http://en.cppreference.com/w/cpp/io/manip/setprecision
In a C++ code I have a matrix of double variables which I print out. However because all of them have different number of digits, the output format is destroyed. One solution is to do
cout.precision(5) but I want different columns have a different precision. Also, because there are negative values in some cases, the presence of the - sign also causes problems. How to get around this and produce a properly formatted output?
Off the top of my head, you can use setw(int) to specify the width of the output.
like this:
std::cout << std::setw(5) << 0.2 << std::setw(10) << 123456 << std::endl;
std::cout << std::setw(5) << 0.12 << std::setw(10) << 123456789 << std::endl;
gives this:
0.2 123456
0.12 123456789
The key is, as others have said, to use manipulators. What they
neglected to say is that you normally use manipulators that you write
yourself. An FFmt manipulator (which corresponds to the F format in
Fortran is fairly easy:
class FFmt
{
int myWidth;
int myPrecision;
public:
FFmt( int width, int precision )
: myWidth( width )
, myPrecision( precision )
{
}
friend std::ostream&
operator<<( std::ostream& dest, FFmt const& fmt )
{
dest.setf( std::ios_base::fixed, std::ios_base::formatfield );
dest.precision( myPrecision );
dest.width( myWidth );
return dest;
}
};
This way, you can define a variable for each column, say:
FFmt col1( 8, 2 );
FFmt col2( 6, 3 );
// ...
and write:
std::cout << col1 << value1
<< ' ' << col2 << value2...
In general, except in the simplest programs, you should probably not be
using the standard manipulators, but rather custom manipulators based on
your application; e.g. temperature and pressure if that's the sort of
thing your dealing with. In this way, it's clear in the code what
you're formatting, and if the client suddenly asks for one more digit in
the pressure, you know exactly where to make the change.
Use manipulators.
From sample here:
#include <iostream>
#include <iomanip>
#include <locale>
int main()
{
std::cout.imbue(std::locale("en_US.utf8"));
std::cout << "Left fill:\n" << std::left << std::setfill('*')
<< std::setw(12) << -1.23 << '\n'
<< std::setw(12) << std::hex << std::showbase << 42 << '\n'
<< std::setw(12) << std::put_money(123, true) << "\n\n";
std::cout << "Internal fill:\n" << std::internal
<< std::setw(12) << -1.23 << '\n'
<< std::setw(12) << 42 << '\n'
<< std::setw(12) << std::put_money(123, true) << "\n\n";
std::cout << "Right fill:\n" << std::right
<< std::setw(12) << -1.23 << '\n'
<< std::setw(12) << 42 << '\n'
<< std::setw(12) << std::put_money(123, true) << '\n';
}
Output:
Left fill:
-1.23*******
0x2a********
USD *1.23***
Internal fill:
-*******1.23
0x********2a
USD ****1.23
Right fill:
*******-1.23
********0x2a
***USD *1.23
Take a look at stream manipulators, especially std::setw and std::setfill.
float f = 3.1415926535;
std::cout << std::setprecision(5) // precision of floating point output
<< std::setfill(' ') // character used to fill the column
<< std::setw(20) // width of column
<< f << '\n'; // your number
Try using setw manipulator. Please refer http://www.cplusplus.com/reference/iostream/manipulators/setw/ for further information
There is a way using i/o manipulators, but I find it unwieldy. I would just write a function like this:
template<typename T>
std::string RightAligned(int size, const T & val)
{
std::string x = boost::lexical_cast<std::string>(val);
if (x.size() < size)
x = std::string(size - x.size(), ' ') + x;
return x;
}