C++ - Why is my cout code displaying decimals inconsistently? - c++

I'm working on an app that needs to print an array through cout on one line, and show 2 decimal places. Currently, my code prints the first two items with 2 decimals, then switches to 1.
Here is the code:
cout << " Inches ";
cout << showpoint << setprecision(2) << right;
for (int i = 0; i < 12; i++)
{
cout << setw(5) << precipitation[i];
}
cout << endl;
And here is the output:
Inches 0.72 0.89 2.0 3.0 4.8 4.2 2.8 3.8 2.7 2.1 1.6 1.0
Can someone please tell me why this change is precision is occurring and what I can do to fix it?
Thanks

You need to use "fixed" mode. In default floating-point mode, precision() sets the number of significant figures to display. In "fixed" mode, it sets the number of places after the decimal. Case in point:
#include <iostream>
using namespace std;
int main(int argc, char **argv) {
float pi = 3.14;
cout.precision(2);
cout << pi << endl;
cout << fixed << pi << endl;
}
Gives the output:
3.1
3.14
HTH.

If you just add cout << fixed before output statements in addition to showpoint and setprecision, you will get a consistent formatting for all outputs.
See below:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double precipitation[12] = { .72, .89, 2, 3, 4.8, 4.2, 2.8, 3.8, 2.7, 2.1, 1.6, 1 };
cout << " Inches ";
cout << showpoint << fixed << setprecision(2) << right;
for (int i = 0; i < 12; i++)
{
cout << setw(5) << precipitation[i];
}
cout << endl;
return 0;
}
Now, the output will be as bellow:
Inches 0.72 0.89 2.00 3.00 4.80 4.20 2.80 3.80 2.70 2.10 1.60 1.00

I was troubled with this problem too. You need to use 'fixed' to do this.
Refer to this link:
C++ setprecision(2) printing one decimal?

Related

How can a floating-point number be printed with more precision?

So i was attempting to code this question Link and i developed the logic and i started coding it. The code is shown below, but there is an issue with it. When i gave the code the following input (Image 1), the output came out to be 2.22582e+007, whereas the correct accepted output is 22258199.500000. What changes should i make in the data type to amend this error. How can i change the notation. Please bear with me as my knowledge of data types is limited.
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
int n,l;
cin >> n;
cin >> l;
vector<float> v;
vector<float> b;
for(int i=0; i<n; i++){
int x;
cin >> x;
v.push_back(x);
}
sort(v.begin(),v.end());
if(v[0]!=0){
b.push_back(v[0]);
for(int i=1; i<n; i++){
b.push_back((v[i] - v[i-1])/2.0);
}
}else if(v[0] == 0){
for(int i=1; i<n; i++){
b.push_back((v[i] - v[i-1])/2.0);
}
}
sort(b.begin(), b.end());
cout << b[b.size()-1];
}
You can use std::cout << std::setprecision(std::numeric_limits<float>::max_digits10) to output the value in a round-trippable format. (This will need headers <limits> and <iomanip>).
If that doesn't work, try also replacing float with double.
You're going to want to use iomanip.
#inlcude <iomanip>
cout<<fixed<<setprecision(6)
fixed will disable the scientific notation.
setprecision will allow you to be as precise as you want.
This resolved the issue.
link
The issue primarily was that the notation of the output was scientific and sometimes the online judges do not accept that, hence to change the notation from scientific to fixed and to other forms, the following code snippet can be used.
Either you can increase the precision or you can change the notation. Either of the latter cases can help.
#include <iostream>
#include <sstream>
int main()
{
std::cout << "The number 0.01 in fixed: " << std::fixed << 0.01 <<
'\n'
<< "The number 0.01 in scientific: " << std::scientific <<
0.01 << '\n'
<< "The number 0.01 in hexfloat: " << std::hexfloat << 0.01
<< '\n'
<< "The number 0.01 in default: " << std::defaultfloat <<
0.01 << '\n';
double f;
std::istringstream("0x1P-1022") >> std::hexfloat >> f;
std::cout << "Parsing 0x1P-1022 as hex gives " << f << '\n';
}
output of the given code - click here

How to "tag" array number with string using a struct?

So I have a loop that takes a line of formatted input that has a name and several numbers and it performs an operation to determine the total score based on those numbers. At the end of the program it is supposed to output the highest score as well as the name of the person who achieved the score. I have a count variable that increases each time it goes through the loop to score the number of the previous "total score" into an array. At the end of the program that array with all the totals is sorted from highest to lowest and then scoretotals[0] is outputted to display the highest score. My question is what is the easiest way to get the name corresponding to that number into a value that can be outputted at the end?
I have tried making a struct and then making that array part of the struct but this brings a lot of errors. So here is my code without attempts to output the name corresponding to the highest score
#include <iostream>
#include <cmath>
#include <string>
#include <fstream>
#include <algorithm>
#include <functional>
#include <iomanip>
using namespace std;
int main()
{
cout << "Name " << "Diff " << "Sorted scores " << "Total" << endl;
struct contestants
{
string name;
double difficulty;
double score1;
double score2;
double score3;
double score4;
double score5;
double score6;
double score7;
double score8;
double score9;
};
contestants person;
ifstream divers ("m6dive.txt");
int count = 0;
double scoretotals[50];
while (divers >> person.name >> person.difficulty >> person.score1 >> person.score2 >> person.score3 >> person.score4 >> person.score5 >> person.score6 >> person.score7 >> person.score8 >> person.score9)
{
double scores[9] = { person.score1, person.score2, person.score3, person.score4, person.score5, person.score6, person.score7, person.score8, person.score9 };
std::sort(scores, scores + 9, std::greater< double >()); //sorts from max to min
double total = (scores[1] + scores[2] + scores[3] + scores[4] + scores[5] + scores[6] + scores[7]) * person.difficulty; //computes score (total excluding min,max multiplied by score)
//outputs name, difficulty, scores sorted and total
cout << person.name << "\t" << std::setprecision(1) << fixed << person.difficulty << "\t" << scores[8] << "\t" << "\t" << scores [7] << " "<< scores [6] << " " << scores[5] << " " << scores[4] << " " << scores [3] << " " << scores [2] << " " <<scores[1] << " " << scores [0] << " " << total << endl;
scoretotals[count] = total;
count++;
}
std::sort(scoretotals, scoretotals + 50, std::greater< double >());
cout << "Highest score is " << scoretotals[0];
}
Output:
Name Diff Sorted scores Total
Anne 2.0 8.0 8.0 8.5 8.5 9.0 9.0 9.0 9.5 9.5 123.0
Sarah 3.0 8.5 8.5 8.5 8.5 9.0 9.0 9.0 9.5 9.5 186.0
Jon 1.5 6.0 7.0 7.5 7.5 7.5 8.0 8.5 8.5 8.5 81.8
Highest score is 186.0
. . .
Instead of storing and sorting scoretotals, store and sort contestant's!!
If you add a function for calculating <, you can call sort() with your own struct!
struct less_than_key {
inline bool operator() (const contestant& c1, const contestant& c2)
{
//Consider making a different function to calculate totals to simplify this copy/paste!
double c1_total = (c1.score1 + ... + c1.score9) * c1.difficulty;
double c2_total = (c2.score1 + ... + c2.score9) * c2.difficulty;
return (c1_total < c2_total);
}
};
And then you can sort with:
std::sort(people, people + 50, less_than_key());
After that, it'd be as simple as pulling out the first person and grabbing their name and total!

Strange compiler behavior

I just hit a strange behavior when compiling a small C++ program with g++ (4.6.3). Compare the two floats celsius and test:
#include <iostream>
using namespace std;
int main () {
float fahrenheit = 0;
float celsius = 0;
float test = 0;
cout << "Temperature in °F: " << endl;
cin >> fahrenheit;
celsius = 5 / 9 * (fahrenheit - 32);
test = 5 * (fahrenheit - 32) / 9;
cout << "\nWrong:\t" << fahrenheit << " °F = " << celsius << " °C" << endl;
cout << "Correct:" << fahrenheit << " °F = " << test << " °C" << endl;
}
I compiled this with just "g++ test.cpp -o test".
This is the output of the program:
$ ./test
Temperature in °F:
1000
Wrong: 1000 °F = 0 °C
Correct:1000 °F = 537.778 °C
Can someone explain to me why g++ does (reproducibly) compute celsius to 0, whereas test contains the correct solution? Does it have anything to do with some optimization, although I didn't set any args for that? Or is this really a bug in some way?
5 / 9 = 0
0 * anything = 0
When you divide to integers, you get an integer back. You can just say 5.0 / 9 and it should be a lot better.
When you're writing code and don't get what you expect, your first inclination should be "what dod I do wrong?" not "what did the compiler do wrong?"
It'll help you look in the right place most of the time.

Using qsort to output ordered list

I have an assignment in my C++ course to get information from a text file that says this:
Scores.txt
PhredrickTheGreat 5.7 5.3 5.1 5.0 4.7 4.8
RobbieTheRock 3.1 4.9 4.1 3.7 4.6 3.9
CannonBallKelly 4.1 5.3 4.9 4.4 3.9 5.4
MartyTheMissile 5.1 5.7 5.6 5.5 4.4 5.3
BillieBomb 5.9 4.8 5.5 5.0 5.7 5.7
JackKnifeJake 5.1 4.7 4.1 3.1 4.6 5.0
Splash 5.1 5.1 4.9 3.4 5.5 5.3
MillyTheMalard 4.9 4.3 5.2 4.5 4.6 4.9
HoraceTheDivingHorse 6.0 6.0 5.7 5.8 5.9 5.9
FishTank 4.3 5.2 5.9 5.3 4.3 6.0
These are the names of fictional baseball players (and batting scores?). The program should output the names of the players, their average score, and then assign them 1st, 2nd, 3rd, etc. place based on their average score. Here's what I have so far:
I commented out a couple of "couts," so you can ignore those.
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
struct Scores
{
float Score;
string Name;
};
float calculateAverage(float RawData){ return RawData / 6.0;}
int main()
{
string Name;
string Score;
float RawScores = 0;
float Average;
Scores ComScores[10];
ifstream playerData("Scores.txt");
for(int i = 0; i < 10; i++)
{
playerData >> Name; // Read in a name
//cout << left << setw(25) << Name << " ";
ComScores[i].Name = Name;
for(int j = 0; j < 6; j++) // Read in Six Scores
{
playerData >> Score;
RawScores += atof(Score.c_str());
//cout << Score << " ";
}
Average = calculateAverage(RawScores);
ComScores[i].Score = Average;
RawScores = 0;
//cout << " Ave: " << fixed << setprecision(2) << Average <<endl;
}
cout << "Place Name Score\n";
cout << "-------------------------------------\n";
for(int i=0; i < 10; i++)
{
if (i < 9){
cout << " " << i+1 << " " << setw(25) << ComScores[i].Name << " " << setw(8) << ComScores[i].Score << endl;
}
else{cout << i+1 << " " << setw(25) << ComScores[i].Name << " " << setw(8) << ComScores[i].Score << endl;}
}
cout << "\n";
cin.get();
return 0;
}
As you can see, I'm almost done I just have to order the places with qsort. My professor gave us one example of using qsort (which I can post), but it didn't really relate to this program (in my point of view). The programs already kinda big and complicated to a novice like me, so, I'm having trouble implementing qsort.
What can I add to my program to sort the last "for loop" to order the list?
I will answer any questions asap.
Here is a way you could do the comparison function :
int score_cmp(const void* a, const void* b)
{
const Scores* sa = (const Scores*)a;
const Scores* sb = (const Scores*)b;
if (sa->Score > sb->Score)
return -1;
else if (sb->Score > sa->Score)
return 1;
else
return 0;
}
And you would call qsort like this:
qsort((void*)ComScores, 10, sizeof(Scores), score_cmp);
That said, you should try to rewrite it yourself once you understand how it's supposed to work, it's not very hard and it's a good exercise.
But note that as #PaulMcKenzie pointed out, calling qsort with a non-trivial type is undefined behavior.
If you must use qsort, a simple but fairly ugly fix would be to replace the string member in struct Scores by a string* and then update the remaining code as needed (the qsort part would not have to change).

Why does setf(ios::fixed) skip the 6th number in a double?

#include <iostream>
using namespace std;
int main() {
double pi = 0.1234567;
cout << "1234567890" << endl;
// cout.width(10);
cout.setf(ios::fixed);
cout << pi << endl;
}
outputs
1234567890
0.123457
Why does it print that instead of 0.123456?
Because it rounds it correctly, that's why. 0.1234567 rounded to 6 decimal places (the default) is 0.123457.