I am trying to count the amount of dollar and coin denominations in a grand total by using a series of while loops. When I get down to the coins however, I am off by a penny. When I enter say 99.95, I get the output 3 quarters, 1 dime, 1 nickel, and 4 pennies. I've narrowed the problem down to a floating point accuracy issue. However all the solutions I've researched haven't been applicable in my situation. Any pointers?
#include <iostream>
using namespace std;
int main()
{
float amount;
cout<<"enter amount" << endl;
cin>>amount;
int pennies=0, nickels=0, dimes=0, quarters=0, ones=0, fives=0,
tens=0,
twenties=0, fifties=0, hundreds=0;
while (amount >= 100)
{
hundreds = hundreds +1;
amount = amount - 100;
}
while (amount >= 50)
{
fifties = fifties +1;
amount = amount - 50;
}
while (amount >= 20)
{
twenties = twenties +1;
amount = amount - 20;
}
while (amount >= 10)
{
tens = tens +1;
amount = amount - 10;
}
while (amount >= 5)
{
fives = fives +1;
amount = amount - 5;
}
while (amount >= 1)
{
ones = ones +1;
amount = amount - 1;
}
while (amount >= .25)
{
quarters = quarters +1;
amount = amount - .25;
}
while (amount >= .10)
{
dimes = dimes +1;
amount = amount - .10;
}
while (amount >= .05)
{
nickels = nickels +1;
amount = amount - .05;
}
while (amount >= .01)
{
pennies = pennies +1;
amount = amount - .01;
}
cout<<endl<<"pennies:"<< pennies;
cout<<endl<<"nickels:"<<nickels;
cout<<endl<<"dimes:"<<dimes;
cout<<endl<<"quarters:"<<quarters;
cout<<endl<<"ones:"<<ones;
cout<<endl<<"fives:"<<fives;
cout<<endl<<"tens:"<<tens;
cout<<endl<<"twenties:"<<twenties;
cout<<endl<<"fifties:"<<fifties;
cout<<endl<<"hundreds:"<<hundreds<<endl;
return 0;
}
Don't use floating point in cases where you need exact values. 99.95 can't be exactly represented in a float or double, a bit like 1/3 can't be exactly represented using a finite number of normal decimal digits.
As Doug T. suggested, you can use an integer to hold the number of pennies. When the user types 123.45, read it as two integers, and then store it as 12345 pennies, not as 123.45 dollars.
In this case, you can also try to change your last while (amount >= .01) to something like while (amount >= .005). It's not a solution that can be generally recommended, and if this is a real-life bank application you really should avoid it, but it will help against at least some of the errors.
You should be using fixed-point values in this case, not floating-point.
Although people think of money in terms of dollars, which aren't exact, money is measured in cents, which are exact. Just count the number of cents, divide by 100 to get the dollar amount, and take the modulus to get the cent amount. Floating-point is not the proper tool in this case.
Binary floating point numbers cannot, in general, represent fractional decimal values, even if the total number of decimals is small. For example, 0.1 cannot be represented exactly.
To deal with exact values different approaches exist which all amount to using a different base than 2. Depending on tge specific needs the approaches are more or less involved. The easieast approach for your case is to use a fixed precision instead of a variable precision. To compute with fixed precision you'd just use an integer which represents the value you actually want multiplied by a suitable power of 10. Depending on the amount of computations you do you can either package the logic into a class or distribute it throughout the code. In a "real" application I'd package it into a class, in an assignment (homework, interview, etc.) I'd probably just apply the logic directly to an int.
Here's the fixed code, I used TJD's advice and instead of using .01 i used .0099 instead. For my problem that seems to work, thanks guys!
#include <iostream>
using namespace std;
int main()
{
float amount;
cout<<"enter amount" << endl;
cin>>amount;
int pennies=0, nickels=0, dimes=0, quarters=0, ones=0, fives=0,
tens=0,
twenties=0, fifties=0, hundreds=0;
float p = .0099, n = .0499, d = .099, q = .2499;
while (amount >= 100)
{
hundreds = hundreds +1;
amount = amount - 100;
}
while (amount >= 50)
{
fifties = fifties +1;
amount = amount - 50;
}
while (amount >= 20)
{
twenties = twenties +1;
amount = amount - 20;
}
while (amount >= 10)
{
tens = tens +1;
amount = amount - 10;
}
while (amount >= 5)
{
fives = fives +1;
amount = amount - 5;
}
while (amount >= 1)
{
ones = ones +1;
amount = amount - 1;
}
while (amount >= q)
{
quarters = quarters +1;
amount = amount - q;
}
while (amount >= d)
{
dimes = dimes +1;
amount = amount - d;
}
while (amount >= n)
{
nickels = nickels +1;
amount = amount - n;
}
while (amount >= p)
{
pennies = pennies +1;
amount = amount - p;
}
cout<<endl<<"pennies:"<< pennies;
cout<<endl<<"nickels:"<<nickels;
cout<<endl<<"dimes:"<<dimes;
cout<<endl<<"quarters:"<<quarters;
cout<<endl<<"ones:"<<ones;
cout<<endl<<"fives:"<<fives;
cout<<endl<<"tens:"<<tens;
cout<<endl<<"twenties:"<<twenties;
cout<<endl<<"fifties:"<<fifties;
cout<<endl<<"hundreds:"<<hundreds<<endl;
return 0;
}
Related
I have been trying to solve this problem for an online judge system, which requires a time limit of 1000ms. I have tried a few variations of solutions, but I will post my best draft here. I was able to get my answers right, however, I am exceeding the time limit. The best solution I can come up with is O(n^2).
The Task problem
Once the programmer X was in China and noticed that Russian clocks “Zarya” are 10 times cheaper there than in Russia. X chose to do some shenanigans and bought a huge amount of clocks to bring it to his own country and sell them at half price (which actually means 5x times more expensive than he bought). But as soon as he came back home, he realized that many clocks go discordantly, moreover, they stop from a simple push (or start going if they were stopped before).
Obviously, the clocks were fake, just very accurate copies. To sell them really quickly, X wants to set them all to the same time (so it won’t matter if the time’s correct or not – he can say this is “the time of the manufacturer”) and just shake his bag to make them tick.
To set the time, he has to spin a winding crown that will make clock’s hands move: the hour hand moves 60 times slower than the minute hand and the minute hand is 60 times slower than the second hand. One full spin of a crown makes a full spin of the second hand; and although the spin takes just a second, it will take 6 minutes to change the time to 6 hours. It is allowed to spin a crown only clockwise to save fragile mechanism of a clock.
Help the programmer X minimize the effort put in preparing the clocks to be sold, choosing the optimal time to set all clocks to.
Input:
The first line contains a natural n (1 ≤ n ≤ 50000) – the quantity of clocks.
The next n lines contain the time of each clock in a format “h:mm:ss”, where h (1 ≤ h ≤ 12) means hours, mm and ss (00 ≤ mm,ss ≤ 59) – minutes and seconds.
Output:
The time all clocks need to be set to in the format presented above.
Example Input
3
11:30:00
12:10:01
6:10:18
Output
12:10:01
#include<iostream>
using namespace std;
struct Clock {
int hours;
int mins;
int secs;
Clock() {
hours = mins = secs = 0;
}
};
void strtotime(string str, Clock& clock) { //converts string input to time
if (str[1] == ':') {
clock.hours = (str[0] - 48);
clock.mins = (str[2] - 48) * 10 + (str[3] - 48);
clock.secs = (str[5] - 48) * 10 + (str[6] - 48);
}
else {
clock.hours = (str[0] - 48) * 10 + (str[1] - 48);
clock.mins = (str[3] - 48) * 10 + (str[4] - 48);
clock.secs = (str[6] - 48) * 10 + (str[7] - 48);
}
}
double calctime(Clock from, Clock to) {//calculates time taken to change one clock time to other's
//calculate time for hours
double minutes;
if (from.hours > to.hours) {
minutes = 12 - (from.hours - to.hours);
}
else {
minutes = to.hours - from.hours;
}
//calculate time for mins
double seconds;
if (from.mins > to.mins) {
seconds = 60 - (from.mins - to.mins);
}
else {
seconds = to.mins - from.mins;
}
//calculate time for secs
double seconds2;
if (from.secs > to.secs) {
seconds2 = 60 - (from.secs - to.secs);
}
else {
seconds2 = to.secs - from.secs;
}
double totalTime = minutes * 60 + seconds + (seconds2 / 60);
return totalTime;
}
int main() {
int n;
string str;
cin >> n;
Clock* clock = new Clock[n];
for (int x = 0; x < n; x++) {
cin >> str;
strtotime(str, clock[x]);
}
double totaltime;
double mintime;
int loc = 0;
bool first = true;
double* timearr = new double[n];
for (int x = 0; x < n; x++) {
totaltime = 0.0;
for (int y = 0; y < n; y++) {
if (x != y) {
totaltime += calctime(clock[y], clock[x]);
}
}
if (first) {
mintime = totaltime;
first = false;
}
else {
if (totaltime < mintime) {
mintime = totaltime;
loc = x;
}
}
}
cout << clock[loc].hours;
cout << ':';
if (clock[loc].mins < 10) {
cout << 0 << clock[loc].mins;
}
else {
cout << clock[loc].mins;
}
cout << ':';
if (clock[loc].secs < 10) {
cout << 0 << clock[loc].secs;
}
else {
cout << clock[loc].secs;
}
}
Sort the times
Calculate the difference between each two neighbors and the first and last element
Find the maximum difference and remove it (the solution is the left neighbor of this difference)
My Basic Algorithm:
Ask for input money amount; Rolls two 6-sided dice; if they add up to 7, add 4 to money amount; else, subtract 1 from money amount; loop until moneyamount<0; loop game user says n when prompted to play again.
/*
*File: hw3
*Author: Nathaniel Goodhue
*
*Created on: 9/15/15
*Description: Game of lucky sevens
*
*/
#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;
int main()
{
srand (time(NULL));
double moneyAmount;
int winValue = 7;
int numRolls = 0;
char playAgain = 'y';
while(playAgain == 'y')
{
cout<<"Enter the amount of money you are playing with: $";
cin>>moneyAmount;
while(moneyAmount>0)
{
int roll1= (rand()%6)+1;
int roll2 = (rand()%6)+1;
if(roll1+roll2 == winValue)
{
moneyAmount+=4;
numRolls++;
}
else
{
moneyAmount-=1;
numRolls++;
}
}
cout<<"It took "<<numRolls<<" roll(s) to lose all of your money"<<endl;
// cout<<"Your maximum amount of money was $" <<maxAmount<<" after "<<maxRolls<<" roll(s)"<<endl;
cout<<"Play again? y/n"<<endl;
cin>>playAgain;
if(playAgain == 'y')
{
cout<<"Enter the amount of money you are playing with: $";
cin>>moneyAmount;
numRolls = 0;
}
else
{
break;
}
}
return 0;
}
Above is my current code. It works as intended. What I am stuck on is that I need to be able to implement this line of code right after money drops below 0:
cout<<"Your maximum amount of money was $" <<maxAmount<<" after "<<maxRolls<<" roll(s)"<<endl;
I need to find out when there was the most money and after how many rolls that it appeared. The maxAmount variable would be the max amount of money achieved, and the maxRolls variable would be the number of rolls when maxAmount was reached.
This is pretty simple to add to your code. What you can do is check if the amount of money they have is greater than the max amount of money. If it is then set max to current and record the number of turns it took to get that value.
int maxAmount = moneyAmount, maxRolls = 0;
while(moneyAmount > 0)
{
int roll1 = (rand() % 6) + 1;
int roll2 = (rand() % 6) + 1;
numRolls++;
if(roll1 + roll2 == winValue)
moneyAmount += 4;
else
moneyAmount -= 1;
if (moneyAmount > maxAmount)
{
// the current amount of money is greater than the max so set max to current and get the number of rolls
maxAmount = moneyAmount;
maxRolls = numRolls;
}
}
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 want to find the largest power of 10 that can divide a given integer.
I have a simplistic implementation for now
int factorBase10Exp(int number){
//...
int mBase10Exp = 0;
while(number%10 == 0 && number != 0)
{
number /= 10; mBase10Exp++;
}
//...
return mBase10Exp;
}
The expected output is
factorBase10Exp(3000) = 3
factorBase10Exp(333) = 0
I can't use std::log10 as log10(333) = 2.522, which would give incorrect results in my use case.
What can I do to make this more efficient?
You can use a series of divisions, each one with half as many digits as the one prior. This gives you a kind of binary search on the number of zeros.
if (number % 100000000 == 0)
{
number /= 100000000;
mBase10Exp += 8;
}
if (number % 10000 == 0)
{
number /= 10000;
mBase10Exp += 4;
}
if (number % 100 == 0)
{
number /= 100;
mBase10Exp += 2;
}
if (number % 10 == 0)
{
number /= 10;
mBase10Exp++;
}
The first division needs to be large enough to cover over half of the largest power of 10 your integer will hold.
So, you actually want to measure how many zeros are in the end of your number when written in decimal form.
If you can find an fast algorithm to convert your number to string, you can then just count zeros.
Given a type Money that is a structured type with two int fields, dollars and cents. Assume that an array named monthlySales with 12 elements, each of type Money has been declared and initialized.
Assume that a Money-variable yearlySales has also been declared. Write the necessary code that traverses the monthlySales-array and adds it all up and stores the resulting total in yearlySales. Be sure make sure that yearlySales ends up with a valid value, i.e. a value of cents that is less than 100.
Now i'm not asking for the answer but, i'm asking how do i approach it. simply because i'm not sure how to address the question like how to code it. I have understand the first paragraph of the question respectively. here is my snippet of code. now im just stuck on how to compute it. i just need a bit of guidance. Thanks!
the code i have so far, accesses the array I have of 12 elements and assigns them random numbers of dollars and cents respectively.
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <cmath>
using namespace std;
struct Money
{
int dollars,cents;
};
int main()
{
Money monthlySales[12], yearlySales;
for (int i = 0; i < 12; i++)
{
monthlySales[i].cents =rand()%99;
monthlySales[i].dollars =rand();
}
return 0;
}
Write the necessary code that traverses the monthlySalesarray and
adds it all up and stores the resulting total in yearlySales. Be sure
make sure that yearlySales ends up with a valid value , i.e. a value
of cents that is less than 100.
Money monthlySales[12], yearlySales;
yearlySales.cents = 0;
yearlySales.dollars = 0;
for (int i = 0; i < 12; i++)
{
yearlySales.cents += monthlySales[i].cents; // Add up the cents
yearlySales.dollars += monthlySales[i].dollars; // Add up the dollars
yearlySales.dollars += yearlySales.cents / 100; // If cents > 100, increase dollars appropriately.
yearlySales.cents = yearlySales.cents % 100; // If cents > 100, set it to the remainder.
}
//to compute Sum
for (int i = 0; i < 12; i++)
{
yearlySales.cents +=monthlySales[i].cents;//keeps adding yearlySales cents for each month
yearlySales.dollars +=monthlySales[i].dollars;//keeps adding yearlySales dollars
}
//if cents 100 convert it into dollars eg:720cents is convereted to 7$ 20 cents and 7 dollars is added to yearly dollars
if(yearlySales.cents > =100)
{
yearlySales.dollars+=yearlySales.cents/100;
yearlySales.cents=yearlySales.cents%100;
}
This works too!
float dollar = 0;
float cent = 0;
for (int i = 0; i < 12; i++) {
dollar += monthlySales[i].dollars;
cent += monthlySales[i].cents;
do {
if (cent > 100 ) {
dollar += 1;
cent -= 100;
}
}while (cent > 100);
}
yearlySales.dollars = dollar;
yearlySales.cents = cent;