print double with variable number of decimals [duplicate] - c++

Running the following code I expect to receive such an output:
Desired output:
Car Hours Charge
1 1.5 2.00
2 4.0 2.50
3 24.0 10.00
But the results comes out as follows:
Actual output:
Car Hours Charge
1 2 2
2 4 2.5
3 2e+01 10
Any suggestions that can guide me to use the correct floating point comparison and using setprecision correctly is welcome.
int main()
{
double hour[3];
double charge[3];
double sum_hour = 0;
double sum_charge = 0;
for (int i = 0; i < 3; i++)
{
cout<<"Enter the hours for car No. "<<i<<": ";
cin>>hour [i];
if (hour [i] <= 3)
{charge [i] = 2.00;}
if (hour [i] > 3 && hour [i] < 24)
{charge [i] = (2.00 + (ceil(hour [i] -3))*0.5);}
if (hour [i] == 24)
{charge [i] = 10.00;}
sum_hour = sum_hour + hour [i];
sum_charge = sum_charge + charge [i];
}
cout<<"Car"<<setw(10)<<"Hours"<<setw(10)<<"Charge"<<endl;
for (int i = 0; i < 3; i++)
{
cout<<i+1<<setw(10)<<setprecision(1)<<hour[i]<<setw(10)<<setprecision(2)<<charge[i]<<endl;
}
cout<<"TOTAL"<<setw(6)<<sum_hour<<setw(10)<<sum_charge<<endl;
}

std::setprecision by default sets the total number of significant digits that are shown (ie. including the ones before the decimal point).
To set the number of digits shown after the decimal point, use std::fixed :
std::cout << std::fixed << std::setprecision(2) << 24.0;
will display :
24.00

You need function fixed to make cout write digits when it got only '0'.
So use it like this:
cout << fixed;
cout<<i+1<<setw(10)<<setprecision(1)<<hour[i]<<setw(10)<<setprecision(2)<<charge[i]<<endl;

Related

Having issues in power digit sum in C++

2^15 = 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26.
What is the sum of the digits of the number 2^1000?
currently I am working on power digit sum in C++. my program is working properly but it gives inappropriate output.
#include<iostream>
#include<math.h>
using namespace std;
long double calculate(long double n)
{
long double i,j,temp = 0,sum = 0;
while(n != 0)
{
temp = fmod(n,10);
sum = sum + temp;
n = n / 10;
}
return sum;
}
int main()
{
long double i,j,n = 1000,temp = 1,value = 0;
for(i = 1;i <= n;i++)
{
temp = temp * 2;
}
cout << "Multiplication is : " << temp << endl;
value = calculate(temp);
cout.precision(100);
cout << "Sum is : " << value << endl;
return 0;
}
I am getting o/p like this.
Multiplication is : 1.07151e+301
Sum is : 1200.63580205668592182366438692042720504105091094970703125
it shouldn't be in points.it should print in digits.
Representing 2^1000 in binary would take a 1000 bits. Doubles are only 64bits long (long doubles are 80 or 128 bits depending on compiler/architecture). So doubles represent 2^1000 approximately. The input to calculate isn't 2^1000, but rather as close an approximation to it as 80bits allow. That approximation does not contain the lowest digits that calculate would like to sum over.
You can't use any primitive datatype to calculate 2^1000 and later sum of its digits, as its a big number (however, in languages like python and ruby you can do it).
For solving this problem in C/C++, you have to use array (or any other linear data structure like linked list, etc) and apply logic similar to usual pen-paper method of multiplying numbers.
First try to find a bound on number of digits in 2^1000 and then initialize an integer array of size greater than it with all zeroes. Keep the last element to be 1. Now multiply the array (thinking it as a large number such that each digit is in a different cell of the array) with 2, thousand times, taking modulo and carry overs.
Here is the code for above logic:
int ar[303];
int sum =0;
ar[0]=1;
for(int j=1;j<303;j++)
ar[j]=0;
for(int i=1;i<1001;i++)
{
ar[0]=2*ar[0];
for(int k=1;k<303;k++)
ar[k]=2*ar[k] + ar[k-1]/10;
for(int j=0;j<303;j++)
ar[j]=ar[j]%10;
}
for(int i=0;i<303;i++)
sum = sum + ar[i];
cout<<sum;
Hope it helps.
The reason why you are getting your sum with decimal points is because you are dividing a double by 10. This will not result in a clean integer unless the doubles last digit before the decimal point is a zero.
example:
376 / 10 = 37.6
370 / 10 = 37
To solve this change this in your code on line 12:
n = (n-temp)/10;
This will cut the float numbers from your sum at least.
finally i have solved my problem.
#include<iostream>
#include<math.h>
#include<string>
using namespace std;
long double calculate(string n)
{
long double i,j,temp = 0,sum = 0;
for (i = 0;i < n.length();i++)
{
if(n[i] == '.')
{
break;
}
sum = sum + (n[i] - 48);
}
return sum;
}
int main()
{
long double i,j,n = 1000,temp = 1,value = 0;
string str;
temp = pow(2,n);
cout << "Power is : " << temp << endl;
str = to_string(temp);
cout << str << endl;
value = calculate(str);
cout.precision(100);
cout << "Sum is : " << value << endl;
return 0;
}

"The Trip" Programming Challenges

Here's the problem.
A group of students are members of a club that travels annually to different locations. Their destinations in the past have included Indianapolis, Phoenix, Nashville, Philadelphia, San Jose, and Atlanta. This spring they are planning a trip to Eindhoven.
The group agrees in advance to share expenses equally, but it is not practical to share every expense as it occurs. Thus individuals in the group pay for particular things, such as meals, hotels, taxi rides, and plane tickets. After the trip, each student's expenses are tallied and money is exchanged so that the net cost to each is the same, to within one cent. In the past, this money exchange has been tedious and time consuming. Your job is to compute, from a list of expenses, the minimum amount of money that must change hands in order to equalize (within one cent) all the students' costs.
Input
Standard input will contain the information for several trips. Each trip consists of a line containing a positive integer n denoting the number of students on the trip. This is followed by n lines of input, each containing the amount spent by a student in dollars and cents. There are no more than 1000 students and no student spent more than $10,000.00. A single line containing 0 follows the information for the last trip.
Output
For each trip, output a line stating the total amount of money, in dollars and cents, that must be exchanged to equalize the students' costs.
Sample Input
3
10.00
20.00
30.00
4
15.00
15.01
3.00
3.01
0
Sample Output
$10.00
$11.99
My code works for some test cases, but fails at others. I think it's because of a precision error in the float. However, I can't find the error.
For example,
Input:
4
9999.1
9999.1
9999.0
9999.1
Output:
$0.06
However, the output should be $0.07
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define MAX 1000
using namespace std;
float money[MAX];
int main(){
int numOfStudents;
int i; // loop counter
double average; // of the costs
double negDiff, posDiff; // |amount-average|
double minDiff;
float total; // all the costs added together
while(scanf("%d", &numOfStudents) == 1){
if(numOfStudents == 0){
break;
}
memset(money, 0, sizeof(money));
total = 0;
for(i = 0; i < numOfStudents; i++){ // scan for the cost of each student - input into array
double m;
scanf("%lf", &m);
money[i] = m;
total += m;
}
average = total/numOfStudents;
negDiff = 0;
posDiff = 0;
for(i = 0; i < numOfStudents; i++){ // find the difference between average and each cost -> add together
if(money[i] > average){
posDiff += (long) ((money[i] - average) * 100.0) / 100.0;
}
else{
negDiff += (long) ((average - money[i]) * 100.0) / 100.0;
}
}
minDiff = 0;
if(posDiff > negDiff){ // find the minimum value for all to equal
minDiff = negDiff;
}
else{
minDiff = posDiff;
}
printf("$%.2lf\n", minDiff);
}
return 0;
}
If you are chopping the positive and negative differences upto 2 decimal places, chop the average also. This gives the result you are expecting (simplified working code)
#include <stdio.h>
int main() {
int n, i;
double average, negDiff, posDiff, minDiff, total;
while (scanf("%d", &n) == 1 && n != 0) {
double money[n];
total = 0.0;
for (i = 0; i < n; i++) {
scanf("%lf", &money[i]);
total += money[i];
}
average = (long) ((total / n) * 100.0) / 100.0;
negDiff = posDiff = 0.0;
for (i = 0; i < n; i++) {
if (money[i] > average)
posDiff += (long) ((money[i] - average) * 100.0) / 100.0;
else
negDiff += (long) ((average - money[i]) * 100.0) / 100.0;
}
minDiff = posDiff > negDiff ? negDiff : posDiff;
printf("$%.2lf\n", minDiff);
}
return 0;
}
Input
3
10.00 20.00 30.00
4
15.00 15.01 3.00 3.01
4
9999.1 9999.1 9999.0 9999.1
0
Output
$10.00
$11.99
$0.07
See http://ideone.com/cxhvlL
Well... you might be right. You really shouldn't be reading the money in as floats.
scanf ("%d.%d", &dollars, &pennies);
int m = dollars * 100 + pennies;
As for solving the problem in general, just make sure you stick to integral division
int average = total / numStudents;
int leftover = total % numStudents;
// numStudents - leftover students need to have paid $average
// leftover students need to have paid $average + 1
int paid = 0;
int recieved = 0;
for (int i = 0; i < numStudents; ++i)
{
// Since we start with the lowest amount owed, money array needs to have been
// sorted such that the student who paid the least comes first.
owed_money = average;
if (i > numStudents - leftover)
owed_money += 1;
if (money[i] < owed_money)
paid += owed_money - money[i];
else if (money[i] > owed_money)
recieved += money[i] - owed_money;
}
assert (paid == recieved);
Maybe there's a better way to do it? In any case, it's a hard problem, but I can promise your solution shouldn't contain any floating point arithmetic.
Calculate the average only down to cents rest needs to be dropped. That means we will be putting x cents in the side pot and since x is going to be less than n, in the end even if you distribute it only few will get and they will be atmost one cent more than others. So they are all with in the cents.
Now with that said. Here is the simple code for that
int main( )
{
int n;
cin >> n;
while( n ) {
vector<double> v;
while( n-- ) {
double x;
cin >> x;
v.push_back( x );
}
double avg = accumulate( begin(v), end(v), 0.0 ) / v.size();
avg = ((int)(avg*100))/100.00;
double exchange = 0;
for ( auto x : v ) { if ( x < avg ){ exchange += avg - x; } }
cout << exchange << endl;
cin >> n;
}
return 0;
}
and for this input
3
10.00
20.00
30.00
4
15.00
15.01
3.00
3.01
4
9999.1
9999.1
9999.0
9999.1
0
output is
10
11.99
0.07

I tried coding my own simple moving average in C++

I want a function that works.
I believe my logic is correct, thus my (vector out of range error) must be coming from the lack of familiarity and using the code correctly.
I do know that there is long code out there for this fairly simple algorithm.
Please help if you can.
Basically, I take the length as the "moving" window as it loops through j to the end of the size of the vector. This vector is filled with stock prices.
If the length equaled 2 for a 2 day moving average for numbers 1 2 3 4. I should be able to output 1.5, 2.5, and 3.5. However, I get an out of range error.
The logic is shown in the code. If an expert could help me with this simple moving average function that I am trying to create that would be great! Thanks.
void Analysis::SMA()
{
double length;
cout << "Enter number days for your Simple Moving Average:" << endl;
cin >> length;
double sum = 0;
double a;
while (length >= 2){
vector<double>::iterator it;
for (int j = 0; j < close.size(); j++){
sum = vector1[length + j - 1] + vector1[length + j - 2];
a = sum / length;
vector2.push_back(a);
vector<double>::iterator g;
for (g = vector2.begin(); g != vector2.end(); ++g){
cout << "Your SMA: " << *g;
}
}
}
}
You don't need 3 loops to calculate a moving average over an array of data, you only need 1. You iterate over the array and keep track of the sum of the last n items, and then just adjust it for each new value, adding one value and removing one each time.
For example suppose you have a data set:
4 8 1 6 9
and you want to calculate a moving average with a window size of 3, then you keep a running total like this:
iteration add subtract running-total output average
0 4 - 4 - (not enough values yet)
1 8 - 12 -
2 1 - 13 13 / 3
3 6 4 15 15 / 3
4 9 8 16 16 / 3
Notice that we add each time, we start subtracting at iteration 3 (for a window size of 3) and start outputting the average at iteration 2 (window size minus 1).
So the code will be something like this:
double runningTotal = 0.0;
int windowSize = 3;
for(int i = 0; i < length; i++)
{
runningTotal += array[i]; // add
if(i >= windowSize)
runningTotal -= array[i - windowSize]; // subtract
if(i >= (windowSize - 1)) // output moving average
cout << "Your SMA: " << runningTotal / (double)windowSize;
}
You can adapt this to use your vector data structure.
Within your outermost while loop you never change length so your function will run forever.
Then, notice that if length is two and closes.size() is four, length + j - 1 will be 5, so my psychic debugging skills tell me your vector1 is too short and you index off the end.
This question has been answered but I thought I'd post complete code for people in the future seeking information.
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<double> vector1 { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
double length;
cout << "Enter number days for your Simple Moving Average:" << endl;
cin >> length;
double sum = 0;
int cnt = 0;
for (int i = 0; i < vector1.size(); i++) {
sum += vector1[i];
cnt++;
if (cnt >= length) {
cout << "Your SMA: " << (sum / (double) length) << endl;
sum -= vector1[cnt - length];
}
}
return 0;
}
This is slightly different than the answer. A 'cnt' variable in introduced to avoid an additional if statement.

setprecision and floating point

Running the following code I expect to receive such an output:
Desired output:
Car Hours Charge
1 1.5 2.00
2 4.0 2.50
3 24.0 10.00
But the results comes out as follows:
Actual output:
Car Hours Charge
1 2 2
2 4 2.5
3 2e+01 10
Any suggestions that can guide me to use the correct floating point comparison and using setprecision correctly is welcome.
int main()
{
double hour[3];
double charge[3];
double sum_hour = 0;
double sum_charge = 0;
for (int i = 0; i < 3; i++)
{
cout<<"Enter the hours for car No. "<<i<<": ";
cin>>hour [i];
if (hour [i] <= 3)
{charge [i] = 2.00;}
if (hour [i] > 3 && hour [i] < 24)
{charge [i] = (2.00 + (ceil(hour [i] -3))*0.5);}
if (hour [i] == 24)
{charge [i] = 10.00;}
sum_hour = sum_hour + hour [i];
sum_charge = sum_charge + charge [i];
}
cout<<"Car"<<setw(10)<<"Hours"<<setw(10)<<"Charge"<<endl;
for (int i = 0; i < 3; i++)
{
cout<<i+1<<setw(10)<<setprecision(1)<<hour[i]<<setw(10)<<setprecision(2)<<charge[i]<<endl;
}
cout<<"TOTAL"<<setw(6)<<sum_hour<<setw(10)<<sum_charge<<endl;
}
std::setprecision by default sets the total number of significant digits that are shown (ie. including the ones before the decimal point).
To set the number of digits shown after the decimal point, use std::fixed :
std::cout << std::fixed << std::setprecision(2) << 24.0;
will display :
24.00
You need function fixed to make cout write digits when it got only '0'.
So use it like this:
cout << fixed;
cout<<i+1<<setw(10)<<setprecision(1)<<hour[i]<<setw(10)<<setprecision(2)<<charge[i]<<endl;

How to display values *only* at every x steps

I'm trying to finish up a program which calculates the natural logarithm of 2, based on the desired # of terms to use and how many values to display after every x step. For example if the user inputs 6 terms, displaying them every 2 steps it would have this output;
0.5000000000
0.5833333333
0.6166666667
instead of:
1.0000000000
0.5000000000
0.8333333333
0.5833333333
0.7833333333
0.6166666667
This loop doesn't work correctly for what I'm trying to do and I'm trying to find out what adjustments to make for it to work. Any help is appreciated.
for(double x = 1; x <= numofterms; x += 1){
logarithm += denominator * 1 / x;
denominator = -denominator;
int printCounter = 0;
for(int i=1; i<=numofterms; i++) {
printCounter++;
if(printCounter >= displaycount) {
cout << setprecision(10) << showpoint << logarithm << endl;
printCounter = 0;
}
You are using printCounter >= displaycount which is wrong
Lets say printCounter is 100 and displaycount is 20 so you should get 6 lines, but after printCounter reaches 20 it will display for every line so you get 81 lines.
So better use printCounter % displaycount == 0 this will only show the lines for 0,20,40,60,80,100 value of printCounter
Here is a code that can do it:
int curPrintStep = displayCount;
for (int i = 1; i <= numOfterms ; i++) {
logarithm += denominator * 1 / (double) i;
denominator = -denominator;
if (i == curPrintStep) {
cout << setprecision(10) << showpoint << logarithm << endl;
curPrintStep += displayCount;
}
}
The variable i contains the current step of the algorithm and at the same time is used to calculate the logarithm.
I set up a step counter variable curPrintStep which is set to the first printing step. Every time I check and if the current step is equal to the print step, I print the logarithm and change the curPrintStep to point to the next print step (by adding displayCount to it).