setw of a specific integer with set precision in C++ - c++

I'm learning the setw and setprecision functions, so here is what I've been trying so far and I have a few questions.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
float y = 1.25;
cout << fixed << setw(10) << setprecision(2) << y << endl;
cout << "\n\n\nx\n";
float x = 213565544.4826;
cout << fixed << setw(13) << setprecision(3) << x << endl;
cout << fixed << setw(14) << setprecision(3) << x << endl;
cout << fixed << setw(15) << setprecision(3) << x << endl;
cout << fixed << setprecision(3) << x;
cout << "\n\n\nz\n";
float z = 213565544.4826;
cout << setw(11) << setprecision(1) << x << endl;
cout << fixed << setw(12) << setprecision(1) << x << endl;
cout << fixed << setw(11) << setprecision(1) << x << endl;
cout << setw(12) << setprecision(1) << x << endl;
cout << "\n\n\nm\n";
float m = -344.275;
cout << fixed << setprecision(1) << x << endl;
cout << fixed << setw(8) << setprecision(1) << x << endl;
cout << fixed << setw(7) << setprecision(1) << x << endl;
cout << fixed << setw(6) << setprecision(1) << x << endl;
return 0;
}
And the input is :
1.25
x
213565552.000
213565552.000
213565552.000
213565552.000
z
213565552.0
213565552.0
213565552.0
213565552.0
m
213565552.0
213565552.0
213565552.0
213565552.0
So, now my questions are :
1) Why do we use "fixed" in first place?
If we look at this example:
cout << setw(11) << setprecision(1) << x << endl;
cout << fixed << setw(11) << setprecision(1) << x << endl;
They output the same value, so what does fixed really change?
2) How does setw work for negative numbers?
In the last example of m. The result is the same for all examples, what does the - sign change in the setw ?
213565552.0
213565552.0
213565552.0
213565552.0
Where do these numbers come from? The value of m is totally different from the ones outputted.
3) Does the . in the number counts as 1 place?
For example, we have number 1.23 and setw(10)
There would be 6 spaces before and then 1.23 (because the dot is counted as 1). Is that true?
4) Why does setprecision is used along with setw? Why does 0000s appear if it's not used? Does it appear as many 0s as the float can handle?
5) Why is the value for x
213565552.000
213565552.000
213565552.000
213565552.000
If x = 213565544.4826.
Where does the numbers 44.4826 get lost?

These seem to be 5 questions rather than one. Anyway:
std::fixed is used to indicate that you always want to have a fixed point format rather than using scientific notation where this notation is more appropriate. When there are many digits needed to represent the value reasonably, the format will switch use x.yyyyyyEee (you can ask to always use scientific format using std::scientific).
std::setw() doesn't care what value is formatted! When a value is formatted and there is a positive out.width() set, the output will be padded with out.fill() character to be at least out.width() characters wide. If the output is bigger than out.width() anyway, no padding will occur. After each output operation [which takes out.width() into account] the out.width() is reset to 0 (all other formatting options are not automatically reset).
Any character counts towards the width, including the sign, thousands separators, decimal points, etc. The decimal point does not count towards the precision: out.precision() is the number of fractional digits (for std::fixed formatting) or the number of non-exponent digits (for std::scientific formatting).
The width is how many characters will be filled by the output, the precision specifies how many [fractional] digits are to be produced.
Binary floating point values can represent very few decimal digits (for float it is normally 6; you can find out how many digits can be safely used by using std::numeric_limits<float>::digits10). Trying to use any more digits than that will probably result in unexpected output when processing decimal values (when processing binary values you may be interested in up to std:numeric_limits<float>::digits places). You might want to have a look at What Every Computer Scientist Should Know About Floating-Point Arithmetic.

Related

What is the purpose of the setprecision() used in this C++ program?

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 do I properly use setprecision() to add ".00" to the end of an amount for money?

I apparently don't know how to set precision. This code should print out the price for a car going through a tollbooth
void TollBooth::arrive(Car c)
{
carcount += 1;
int cost;
int doors = c.getDoors();
cost = 3 + doors;
total+=cost;
cout << setw(12) << left << "Car: "<< setw(8) <<c.getID()<< setw(8)
<< " Amount Due: $ " << setw(5) << fixed << right << setprecision(2) << cost << endl;
}
However what prints out is the "cost" without trailing zeroes.
Don't use setprecision, just echo the trailing .00 directly (and adjust the preceding setw):
void TollBooth::arrive(Car c)
{
carcount += 1;
int doors = c.getDoors();
int cost = 3 + doors;
total += cost;
cout << setw(12) << left << "Car: "<< setw(8) <<c.getID()<< setw(8) << " Amount Due: $ "
<< setw(3) << right << cost << ".00" << endl;
}
You could cast to floating point, and for an int value, using double should be safe on all architectures I'm aware of. Don't cast to float though; as I noted in a comment, IEEE 32 bit floats don't have the precision to represent the entire range of int (e.g. (1 << 24) + 1 becomes equal to 1 << 24 when cast to IEEE 32 bit float). Best to avoid the risk of a precision error when it's not necessary.
For your particular case it is not adding the trailing zeros because cost is declared as an integer in your code. You need to cast it to double or float(although it might result in data loss for some integer values).
cout << setw(12) << left << "Car: "<< setw(8) <<c.getID()<< setw(8) << " Amount Due: $ "
<< setw(5) << fixed << right << setprecision(2) << static_cast<double>cost << endl;
BTW you may want to read the links given in the comment section of your question.
As others wrote, the reason is that you are using ints instead of doubles, but anyway. Whether you can use doubles to represent currency is somwhat up to debate. I wouldn't do it, but for most non-financial software (like games, school projects, keeping track of your monthly income and expenses) it's good enough.
However, comminig back to your actual problem: If you want to format monetary values, you probably want to use std::put_money instead of plain floating point formatting anyway.
You can use setprecision and showpoint:
double a = 14;
cout << setprecision(4) << showpoint << a;
Output:
14.00
Downside is you would have to calculate the setprecision argument.

How to properly set precision for doubles in C++

I'm working on a project where I need to do some math and give the user output with dollars in it, so I would like to have my console tell the user an answer like $20.15 instead of $20.153. I used the set precision function as such:
cout << setprecision(2);, but rather than have the numbers become what I want them to be, they are converted into scientific notation.
I'm outputting a lot of numbers, so having a function like setprecision would be best for me for ease of use.
How do I properly have the numbers displayed with only two decimal places and not have the console give me numbers in scientific notation?
Thanks
Nathan
EDIT:
Here is the part of my code I'm having problems with:
int main() {
cout << setprecision(2);
if (totalCostHybrid < totalCostNonHybrid) {
cout << "Hybrid car: " << endl;
cout << "Total cost: " << totalCostHybrid << endl;
cout << "Total gallons used: " << milesPerYear / hybridEffic << endl;
cout << "Total gas cost: " << gasCostHybrid << endl;
cout << "Non-hybrid car: " << endl;
cout << "Total cost: " << totalCostNonHybrid << endl;
cout << "Total gallons used: " << milesPerYear / nonHybridEffic << endl;
cout << "Total gas cost: " << gasCostNonHybrid << endl;
cout << "Hybrid is cheaper!" << endl;
}
Obviously there's more to it, but this is what I need help with.
To fix that, you should use fixed floating-point notation for cout. You can find more info here.
Try addind cout << fixed to your code, like the code below. To set the precision to 2, you can use the precision property.
cout << fixed;
cout.precision(2);
Here is the complete code:
using namespace std;
int main() {
cout << fixed;
cout.precision(2);
if (totalCostHybrid < totalCostNonHybrid) {
cout << "Hybrid car: " << endl;
cout << "Total cost: " << totalCostHybrid << endl;
cout << "Total gallons used: " << milesPerYear / hybridEffic << endl;
cout << "Total gas cost: " << gasCostHybrid << endl;
cout << "Non-hybrid car: " << endl;
cout << "Total cost: " << totalCostNonHybrid << endl;
cout << "Total gallons used: " << milesPerYear / nonHybridEffic << endl;
cout << "Total gas cost: " << gasCostNonHybrid << endl;
cout << "Hybrid is cheaper!" << endl;
}
}
Iostreams are a pain for formatting floating-point values. But why are you using floating-point to represent currency values? You should store integer pennies (or tenth-pennies) because, though you're not measuring in whole numbers of dollars, your values are actually fixed-point. And you really don't need the trouble that floating-point brings. And then you can stream the whole and "fractional" parts of your value separately (use / and %!), as integers, with a '.' in the middle.
In the meantime, try std::fixed.
Cheat and watch purists go crazy...
double time; //Only want two decimal places.
double timeCon = time * 100.0; //Pull out the two decimals I want.
int timeCut = timeCon; //Cut all decimal values.
double timeRevert = timeCut / 100.0; //Laugh.
cout << timeRevert << endl; //Watch heads explode.

C++ setprecision(2) printing one decimal?

I'm trying to do some simple output in formatted text. Setprecision is not printing my variables out to two decimal places.
For example if firstItemPrice = 2.20, the output is 2.2 instead of 2.20
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
string firstitem = "";
string seconditem = "";
double firstItemNum;
double firstItemPrice = 0.00;
double secondItemNum;
double secondItemPrice = 0.00;
//first item
cout << "Enter the name of Item 1: ";
getline(cin, firstitem);
cout << "Enter the number of " << firstitem << "s and the price of each: ";
cin >> firstItemNum >> firstItemPrice;
cin.ignore();
//second item
cout << "Enter the name of Item 2: ";
getline(cin, seconditem);
cout << "Enter the number of " << seconditem << "s and the price of each: ";
cin >> secondItemNum >> secondItemPrice;
cout << left << setw(20) << "Item" << setw(10) << "Count"
<< setw(10) << "Price" << left << "\n";
cout << setw(20) << "====" << setw(10) << "====" << setw(10)
<< "====" << left << "\n";
cout << setw(20) << firstitem << setw(10)
<< firstItemNum << setw(10) << setprecision(2)
<< firstItemPrice << "\n";
cout << setw(20) << seconditem << setw(10) << secondItemNum
<< setprecision(2) << secondItemPrice << left << "\n";
return 0;
}
You need a fixed in there to do that.
cout << fixed;
Set it back using:
cout.unsetf(ios_base::floatfield);
In your case, changing the last bit of your program like this example should do it:
cout << setw(20) << firstitem << setw(10)
<< firstItemNum << setw(10) << fixed << setprecision(2)
<< firstItemPrice << "\n";
cout.unsetf(ios_base::floatfield);
cout << setw(20) << seconditem << setw(10) << secondItemNum
<< fixed << setprecision(2) << secondItemPrice << left << "\n";
Editorial aside: Don't use floating point numbers to represent currency values.
from http://www.cplusplus.com/reference/ios/ios_base/precision/
The floating-point precision determines the maximum number of digits to be written on insertion operations to express floating-point values. How this is interpreted depends on whether the floatfield format flag is set to a specific notation (either fixed or scientific) or it is unset (using the default notation, which is not necessarily equivalent to either fixed nor scientific).
For the default locale:
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.
In both the fixed and scientific notations, the precision field specifies exactly how many digits to display after the decimal point, even if this includes trailing decimal zeros. The digits before the decimal point are not relevant for the precision in this case.

C++ Problems Displaying Doubles with cout

I have this simple class and can't figure out how to get the doubles to display properly.
Currently the are displayed as "0.00". Without 'showpoint' and 'setprecision()' they were displaying as random numbers (ex: 6.95326e-310). Minutes is an integer, price is where the problem is
output() const{
cout << "Title: " << title;
cout << fixed << showpoint << setprecision(2) <<
"\nMinutes: " << get_minutes() << "\nPrice: ";
cout << fixed << showpoint << setprecision(2) << get_price();
cout << "\n";
6.95326e-310 is not a random number. It's called scientific notation and is able to show very small or very large numbers without using too many digits. If you don't want that, then set a default precision on cout:
std::cout.precision(2);