This question already has answers here:
Why does dividing two int not yield the right value when assigned to double?
(10 answers)
Closed 7 months ago.
I've been working on problems out of D.S. Malik C++ Programming book and I'm not looking for an answer but an explanation as to why in my charges function does billingAmount return 0 for incomeLow (Line 135). If I answer 70 for hourly rate, 15000 for customers income, and 75 for consulting time I should get $21.00
(70 * 40 * (45 / 60)) = $21.00
45 comes from subtracting 30 from 75 minutes since anything less than 30 minutes charges are free (0).
#include <iostream>
#include <iomanip>
using namespace std;
// Declared function identifiers
bool check_number(string str);
double hourly_rate();
double customer_income();
int consult_time();
double charges(double revenue, double rate, int time, bool incomeLow);
string tempRate;
string tempIncome;
string tempConsultTime;
int main()
{
int income = 0;
int consultTime = 0;
double hourlyRate = 0;
bool lowIncome = false;
hourlyRate = hourly_rate();
while (income <= 0)
{
income = customer_income();
}
if (income <= 25000) {
lowIncome = true;
}
consultTime = consult_time();
cout << fixed << showpoint << setprecision(2);
cout << "Billing Amount: "
<< charges(income, hourlyRate, consultTime, lowIncome)
<< "Low Income: " << lowIncome;
return 0;
}
bool check_number(string str) {
for (int i = 0; i < str.length(); i++) {
if (!isdigit(str[i])){
if (str[i] == '-'){
return false;
}
if (str[i] == '.'){
return true;
}
return false;
}
}
return true;
}
double hourly_rate()
{
cout << "Enter the hourly rate or 'n' to exit: ";
cin >> tempRate;
while(!check_number(tempRate))
{
if (tempRate[0] == 'n')
{
exit(0);
}
cout << "Error: Enter a positive hourly rate or 'n' to exit: ";
cin >> tempRate;
}
return stod(tempRate);
}
double customer_income()
{
cout << "Enter customers income or 'n' to exit: ";
cin >> tempIncome;
while(!check_number(tempIncome) || tempIncome == "0")
{
if (tempIncome[0] == 'n')
{
exit(0);
}
cout << "Error: Enter a positive integer or 'n' to exit: ";
cin >> tempIncome;
}
return stod(tempIncome);
}
int consult_time()
{
cout << "Enter the amount of consulting time (in minutes): ";
cin >> tempConsultTime;
while(!check_number(tempConsultTime))
{
if (tempConsultTime[0] == 'n')
{
exit(0);
}
cout << "Error: Enter a positive consult time (in minutes) or 'n' to exit: ";
cin >> tempConsultTime;
}
return stoi(tempConsultTime);
}
double charges(double revenue, double rate, int time, bool incomeLow){
double billingAmount;
int T;
if (incomeLow) {
if (revenue <= 25000 && time <= 30)
{
return 0;
} else if (revenue <= 25000 && time > 30) {
T = time - 30;
billingAmount = rate * 40 * (T / 60);
}
}
if (!incomeLow && time <= 20) {
return 0;
} else {
T = time - 30;
billingAmount = rate * 70 * (T / 60);
}
return billingAmount;
}
You obviously think that (45 / 60) is 0.75. In ordinary math it would be, but in C++ this is integer division and the result is always an integer (truncated towards zero). In effect 0.75 is rounded down to 0.
Just change (T / 60) to (T / 60.0) and you are no longer doing integer division and the result will be 0.75.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 12 months ago.
Improve this question
I am writing a program to calculate the grade of 3 test scores. The lowest of the first 2 scores is dropped and added to the third test score to make the final grade. The 3 test scores cannot be higer than 50, lower than 0 and cannot be a character or string. So far, I have satisified all those requirment but I need to implement decimal grades to the program like for instance 45.5. Also to round the final grade up or down. For example if final grade is 89.5 round up to an A.
#include <iostream>
#include <algorithm>
#include <cstdlib>
using namespace std;
char getGrade(int num) {
if (num < 60)
return 'F';
if (num < 69)
return 'D';
if (num < 79)
return 'C';
if (num < 89)
return 'B';
return 'A';
}
bool isnumeric(string temp) {
for (char &chr : temp) {
if ((chr >= '0' and chr <= '9') or chr == '-')
continue;
else
return false;
}
return true;
}
int main(int argc, char const *argv[]) {
cout << "Welcome to the grade calculator.You will input three test "
"scores.\nThe highest of the first two grades and the third grade "
"will be\nadded together to determine the numeric grade average for "
"the\ncourse.Each test score has a maximum of 50 points.\n";
int arr[3];
int ctr = 0;
string temp;
int num;
while (ctr < 3) {
cout << "\nPlease enter test score " << (ctr + 1) << ": ";
label1:
cin >> temp;
if (isnumeric(temp)) {
num = atoi(temp.c_str());
if (num > 50) {
cout << "\nTest scores cannot be higher than 50, try again: ";
goto label1;
} else if (num < 0) {
cout << "\nTest scores cannot be negative, try again: ";
goto label1;
} else {
arr[ctr++] = num;
}
} else {
cout << "\nInvalid test score entered, try again: ";
goto label1;
}
}
int average = 0;
average = max(arr[0], arr[1]);
average = average + arr[2];
cout << "\nThe average for the course = " << average << "\n";
cout << "The letter grade = " << getGrade(average);
cout << "\n\n\nThank you for using this program\n";
return 0;
}
Just changed a couple of things to make it work with decimals:
1. Added chr == '.' to the isNumeric() function:
bool isnumeric(string temp) {
for (char& chr : temp) {
if ((chr >= '0' and chr <= '9') or chr == '-' or chr == '.')
continue;
else return false;
}
return true;
}
2. Changed variable types:
double arr[3]{};
int ctr = 0;
std::string temp;
double num;
3. Removed goto: (You can just use continue)
while (ctr < 3) {
std::cout << "\nPlease enter test score " << (ctr + 1) << ": ";
std::cin >> temp;
if (isnumeric(temp)) {
num = atof(temp.c_str());
if (num > 50) {
std::cout << "\nTest scores cannot be higher than 50, try again: ";
continue;
}
else if (num < 0) {
std::cout << "\nTest scores cannot be negative, try again: ";
continue;
}
else {
arr[ctr++] = num;
}
}
else {
std::cout << "\nInvalid test score entered, try again: ";
continue;
}
}
4. For rounding off, you can use std::round() as such:
double average = 0;
average = std::max(arr[0], arr[1]);
average = std::round(average + arr[2]);
You can also change your cout statements:
std::cout << "\nThe average for the course = " << average;
if (std::round(average) != average) std::cout << ", rounded off to = " << std::round(average);
std::cout << ".\nThe letter grade = " << getGrade(average);
std::cout << "\n\n\nThank you for using this program\n";
Just make all these changes and your program will successfully work with decimals.
Also, consider not using the following in your code:
using namespace std;
..as it's considered as a bad practice. For more info on why, look up to Why is using namespace std considered as a bad practice.
Edit: To accomplish your requirement, you can just change the while loop as such:
while (ctr < 3) {
if (temp.size() == 0)
{
std::cout << "\nPlease enter test score " << (ctr + 1) << ": ";
std::cin >> temp;
}
if (isnumeric(temp)) {
num = atof(temp.c_str());
if (num > 50) {
std::cout << "\nTest scores cannot be higher than 50, try again: ";
std::cin >> temp;
continue;
}
else if (num < 0) {
std::cout << "\nTest scores cannot be negative, try again: ";
std::cin >> temp;
continue;
}
else {
arr[ctr++] = num;
temp.clear();
}
}
else {
std::cout << "\nInvalid test score entered, try again: ";
std::cin >> temp;
continue;
}
}
The above code works as you said.
I have made a program that sort dates and displays them year-wise. 0+years, 10+years, 20+years, etc. I have also validated the date. For example, there should be no more than 31 or less than 1 days. I also have validation for leap years, months etc. How do I check if format of date is valid or not? I want to should show an error message that the date format is incorrect on inputting date as 6/7/2008 or 6/07/2008. The format should be dd/mm/yyyy.
Person People::getPerson()
{
Person person;
Validation validate;
string input;
bool ch;
int memNo = 0;
cout << " \nEnter another Person\n" << "Membership Number: ";
cin >> memNo;
person.SetMemNo(memNo);
//While the input entered is not an integer, prompt the user to enter an integer.
while(cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<int>::max(), '\n');
cout << "Invalid data. Please type an integer! " << endl;
cout << "Membership Number: ";
cin >> memNo;
cout << endl;
}
cout << "Enter first name of person: ";
cin >> input;
bool onlystring = validate.IsDigitsOnly(input);
//validate string for only alphabets,no numbers
if (onlystring == true) {
cout << "Enter only alphabets for first name" << endl;
cout << "Enter first name of person: ";
cin.clear();
cin.ignore();
cin >> input;
}
person.SetFirstName(input);
cout << "Enter your Surname ";
cin >> input;
person.SetLastName(input);
bool onlystring1 = validate.IsDigitsOnly(input); //validate string for only alphabets,no numbers
if (onlystring1 == true) {
cout << "Enter only alphabets for last name" << endl;
cout << "Enter your Surname ";
cin >> input;
}
bool valid_date = false;
do {
cout << "Enter your date of joining(DD/MM/YYYY): ";
cin >> input;
string new_date= validate.checkFormat(input);
valid_date = validate.valDate(new_date);
if (valid_date == true)
person.SetDateJoined(new_date);
else
cout << "Invalid Date!Please re-enter date of joining!" << endl;
} while(valid_date == false);
date validation
bool Validation::valDate(string input)
{
int Y = stoi(input.substr(6));
int M = stoi(input.substr(3, 2));
int D = stoi(input.substr(0, 2));
//check year
if (Y >= 1900 && Y <= 9999)
{
//check month
if (M >= 1 && M <= 12)
{
//check days
if ((D >= 1 && D <= 31) && (M == 1 || M == 3 || M == 5 || M == 7 || M == 8 || M == 10 || M == 12)) {
return true;
}
else if ((D >= 1 && D <= 30) && (M == 4 || M == 6 || M == 9 || M == 11)) {
return true;
}
else if ((D >= 1 && D <= 28) && (M == 2)) {
return true;
}
else if (D == 29 && M == 2 && (Y % 400 == 0 || (Y % 4 == 0 && Y % 100 != 0))) {
return true;
}
else {
return false;
}
}
else
{
return false;
}
}
else
{
printf("Year is not valid.\n");
return false;
}
return 0;
}
int Validation::Prepend_function ( int n) {
if (n < 10 && n < 0) {
string num = to_string(n);
string new_num = "0" + num;
int number = stoi(new_num);
return number;
}
else {
return n;
}
}
string Validation::checkFormat(string input)
{
//check the length of the string
int len = input.size();
if (len != 10)
{
int year = stoi(input.substr(4));
int month = stoi(input.substr(2, 1));
int day = stoi(input.substr(0, 1));
int prepend_day = Prepend_function(day);
int prepend_month = Prepend_function(month);
string day1 = to_string(prepend_day);
string month1 = to_string(prepend_month);
string year1 = to_string(year);
string date = day1+"/"+month1+"/"+year1;
return date;
}
}
I think you are asking how to implement Validation::checkFormat, because Validation::valDate doesn't seem incorrect.
std::string Validation::checkFormat(std::string input)
{
std::stringstream in(input);
int day, month, year;
char ignore;
// Match num/num/num, otherwise invalid
if (in >> day >> ignore >> month >> ignore >> year)
{
std::stringstream out;
// Force leading 0s
out << std::setfill('0') << std::setw(2) << day << '/' << month << '/' << std::setw(4) << year;
return out.str();
}
// have to return something if it isn't valid
return std::string();
}
Note that checkFormat sounds to be the wrong name for returning a string formatted in a particular way. I would call it fixFormat, and compare input to the result of fixFormat. If they are the same, then input is in the specified format
The goal of these functions in the end is to show someone's total fee's for being consulted, which is based off whether or not they have a low income. The functions are supposed flow downwards to get each needed value in order to calculate the total. I do not understand how to fix the various errors in my code, such as some variables not being declared in a specific scope, even though I thought i declared them correctly.
#include <iostream>
using namespace std;
const double HighIncomeRate = .7;
const double LowIncomeRate = .4;
bool isLowIncome();
int main() {
double Fee;
double ConsultTime;
cout << "Your fee is: " << getcalcFee(consultTime, Income) << endl;
return 0;
}
bool isLowIncome() {
double Income;
cout << "What is your income: " << endl;
cin >> Income;
cout << "How long have you been consulted" << endl;
cin >> ConsultTime;
if (Income <= 25000) {
return true;
} else {
return false;
}
}
double calcFee(int &ConsultTime, const double HighIncomeRate,
const double LowIncomeRate) {
if (isLowIncome == true) {
if (ConsultTime <= 30) {
calcFee = 0
} else {
calcFee = LowIncomeRate * 50((ConsultTime - 30) / 60)
}
}
if {
if (ConsultTime <= 20) {
calcFee = 0
} else {
calcFee = HighLowRate * 50((ConsultTime - 20) / 60)
}
}
return 0;
}
currently, I am having an issue with this if/else statement. this is the source here:
#include "stdafx.h"
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
string firstname, secondname;
const int A_SCORE = 90;
const int B_SCORE = 80;
const int C_SCORE = 70;
const int D_SCORE = 60;
int testscore1;
int testscore2;
int testscore3;
int testscore4;
int testscore5;
int testscore6;
int testscore7;
int testscore8;
int testscore9;
int testscore10;
cout << "Enter your 10 scores and I will average\n"
<< "the total score, and assign letter grades" << endl;
cin >> testscore1;
cin.ignore();
cin >> testscore2;
cin.ignore();
cin >> testscore3;
cin.ignore();
cin >> testscore4;
cin.ignore();
cin >> testscore5;
cin.ignore();
cin >> testscore6;
cin.ignore();
cin >> testscore7;
cin.ignore();
cin >> testscore8;
cin.ignore();
cin >> testscore9;
cin.ignore();
cin >> testscore10;
cin.ignore();
int sum = testscore1 + testscore2 + testscore3 + testscore4 + testscore5 + testscore6 + testscore7 + testscore8 + testscore9 + testscore10;
int average = sum / 10;
if (average == 90);
{
cout << "your average is an A.";
}
else if (average == 80);
{
cout << "you have an average of a B.";
}
else if (average == 70);
{
cout << "you have an average of a C.";
}
else (average == 60);
{
cout << "your average is a D.":
}
system("pause");
return 0;
}
what the goal of this homework assignment is, is to input 10 numerical grades and have an average print out to screen with a letter grade based on average of the 10 grades. I no matter what I input, I always get 'your grade is an A. I have went over my notes ad well as looking to goodle/StackOverflow for what could be wrong. I also get compile errors too, which I cannot figure out. If someone could give me any ideas on what could be causing the issue, I would greatly appreciate it!
Remove the semicolons after the if statements and instead of checking for the values to be exactly 90/80/70 try something like this:
if(average >= 90)
{
//print
}
If you want more accurate results try using floats instead of integers.
Your if-statements should take the form of if(average >= 90, 80, etc...).
Also, what are your errors?
EDIT:
if (average >= 90)
{
cout << "your average is an A.";
}
else if (average >= 80)
{
cout << "you have an average of a B.";
}
else if (average >= 70)
{
cout << "you have an average of a C.";
}
else if(average >= 60)
{
cout << "your average is a D.";
}
else
{
cout << "your average is an F.";
}
return 0;
You needed to remove all of the semicolons, one colon, change your relational operator from == to >=, and add an extra else to catch anything below 60.
If..else statements are conditional. You need to provide the accurate conditions to get the results that you expect.
Try:
if (average >= A_SCORE)
{
cout << "your average is an A.";
}
else if (average >= B_SCORE)
{
cout << "you have an average of a B.";
}
else if (average >= C_SCORE)
{
cout << "you have an average of a C.";
}
else if(average >= D_SCORE)
{
cout << "your average is a D.";
}
else
{
cout << "your average is an F.";
}
system("pause);
I am new to C++ and am having trouble passing string back to the main class of my code.
My goal is to split the below code so that I have 2 functions other than the main class and at least one must return a value other than 0.
Beginning code:
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
cout.precision(2);
cout.setf(ios::fixed,ios::floatfield);
float speedLimit;
float driversSpeed;
float ticketAmount;
float speedOver;
string repeat;
/*Use a symbolic constant for the base ticket fine rate ($50).*/
const float base = 50;
start:
/*Prompt the user for the speed limit and the speed of the driver.*/
cout << "Enter the speed limit: ";
cin >> speedLimit;
cout << "Enter the driver's speed: ";
cin >> driversSpeed;
cout << "You were driving " << driversSpeed << " in a " << speedLimit << " mph zone.\n";
speedOver = driversSpeed - speedLimit;
if (speedOver <= 10 && speedOver >= 1)
{
ticketAmount = base;
}
else if (speedOver <= 14 && speedOver >= 11)
{
ticketAmount = (base *.05) + base;
}
else if (speedOver <= 19 && speedOver >= 15)
{
ticketAmount = (base *.1) + base;
}
else if (speedOver <= 24 && speedOver >= 20)
{
ticketAmount = (base *.15) + base;
}
else if (speedOver <= 29 && speedOver >= 25)
{
ticketAmount = (base *.2) + base;
}
else if (speedOver >= 30)
{
ticketAmount = (base *.25) + base;
}
else
{
ticketAmount = 0;
}
cout << "Your fine is $" << ticketAmount;
cout << "\nEnter Y to continue. Anything else to stop: ";
cin >> repeat;
if (repeat == "Y" || "y")
goto start;
else
exit(0);
return 0;
}
and here what I have done so far:
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
const float base = 50;
float speedLimit;
float driversSpeed;
float ticketAmount;
float speedOver;
int _tmain(int argc, _TCHAR* argv[])
{
cout.precision(2);
cout.setf(ios::fixed,ios::floatfield);
string repeat;
/*Use a symbolic constant for the base ticket fine rate ($50).*/
start:
/*Prompt the user for the speed limit and the speed of the driver.*/
cout << "Enter the speed limit: ";
cin >> speedLimit;
cout << "Enter the driver's speed: ";
cin >> driversSpeed;
/*Display to the user the values which were input (speed limit and driver's speed) and the calculated ticket fine amount. Print 2 numbers after the decimal point for the fine amount. Make sure your output format matches the sample format.*/
cout << "You were driving " << driversSpeed << " in a " << speedLimit << " mph zone.\n";
speedOver = driversSpeed - speedLimit;
cout << string(finalOutput);
/*After the fine is printed for the first speeding violation, prompt the user to see if he/she wants to enter another speeding violation. If so, prompt again for the speed limit and driver's speed. Repeat the calculation and print the fine. Repeat this process until the user indicates he/she wants to stop. The user can enter either an uppercase or lowercase letter Y to continue with the program.*/
cout << "\nEnter Y to continue. Anything else to stop: ";
cin >> string(repeat);
if (repeat == "Y" || "y")
goto start;
else
exit(0);
}
float ticketAmountFunc(float ticketAmount)
{
/*Calculate the ticket cost as $50 (the base fine rate) plus:
0% additional if the driver's speed was 10 or less miles per hour above the speed limit.
5% additional if driver's speed was more than 10 miles per hour above the speed limit.
10% additional if driver's speed was more than 15 miles per hour above the speed limit
15% additional if driver's speed was more than 20 miles per hour above the speed limit.
20% additional if driver's speed was more than 25 miles per hour above the speed limit.
25% additional if driver's speed was 30 or more miles per hour above the speed limit.
Do not charge a fine if the driver wasn't speeding.*/
if (speedOver <= 10 && speedOver >= 1)
{
ticketAmount = base;
}
else if (speedOver <= 14 && speedOver >= 11)
{
ticketAmount = (base *.05) + base;
}
else if (speedOver <= 19 && speedOver >= 15)
{
ticketAmount = (base *.1) + base;
}
else if (speedOver <= 24 && speedOver >= 20)
{
ticketAmount = (base *.15) + base;
}
else if (speedOver <= 29 && speedOver >= 25)
{
ticketAmount = (base *.2) + base;
}
else if (speedOver >= 30)
{
ticketAmount = (base *.25) + base;
}
else
{
ticketAmount = 0;
}
return ticketAmount;
}
string finalOutput(string tix)
{
string words = "Your fine is $";
//tix = words + ticketAmountFunc;
tix += string(words) + string(ticketAmountFunc);
return tix;
}
VS is returning 2 errors:
Error 1 error C2065: 'finalOutput' : undeclared identifier
Error 7 error C2440: '<function-style-cast>' : cannot convert from 'float (__cdecl *)(f
loat)' to 'std::string'
Could someone please poing me in the direction of my error?
Thank you.
EDIT: Thank you Ben. I moved my main method and tried moving variables around to declare them as strings and still have the undeclared identifier issue but now twice.
Here is my updated code:
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
const float base = 50;
float speedLimit;
float driversSpeed;
float ticketAmount;
float speedOver;
string ticketAmountFunc(string r)
{
string ticketAmount;
if (speedOver <= 10 && speedOver >= 1)
{
ticketAmount = base;
}
else if (speedOver <= 14 && speedOver >= 11)
{
ticketAmount = (base *.05) + base;
}
else if (speedOver <= 19 && speedOver >= 15)
{
ticketAmount = (base *.1) + base;
}
else if (speedOver <= 24 && speedOver >= 20)
{
ticketAmount = (base *.15) + base;
}
else if (speedOver <= 29 && speedOver >= 25)
{
ticketAmount = (base *.2) + base;
}
else if (speedOver >= 30)
{
ticketAmount = (base *.25) + base;
}
else
{
ticketAmount = "0";
}
std::string s = ticketAmount;
r = s;
return r;
}
string finalOutput(string tix)
{
string words = "Your fine is $";
//tix = words + ticketAmountFunc;
tix = string() + words + ticketAmountFunc(r);
return tix;
}
int _tmain(int argc, _TCHAR* argv[])
{
cout.precision(2);
cout.setf(ios::fixed,ios::floatfield);
string repeat;
/*Use a symbolic constant for the base ticket fine rate ($50).*/
start:
/*Prompt the user for the speed limit and the speed of the driver.*/
cout << "Enter the speed limit: ";
cin >> speedLimit;
cout << "Enter the driver's speed: ";
cin >> driversSpeed;
cout << "You were driving " << driversSpeed << " in a " << speedLimit << " mph zone.\n";
speedOver = driversSpeed - speedLimit;
cout << string(finalOutput(tix));
cout << "\nEnter Y to continue. Anything else to stop: ";
cin >> string(repeat);
if (repeat == "Y" || "y")
goto start;
else
exit(0);
}
and my errors are:
Error 7 error C2065: 'r' : undeclared identifier
Error 8 error C2065: 'tix' : undeclared identifier
You're trying to use the functions before their "point of declaration". There are two simple solutions (pick one):
Add a forward declaration aka prototype before you use it.
Move the caller (main()) below the functions it uses.
Also, when calling a function, you need to provide its arguments inside parentheses. So you need to say ticketAmountFunc(ticketAmount) and not just ticketAmountFunc.
In addition to these problems, you seem to be defining function parameters as the value the function generates, instead of the data it uses. That's not useful. When you use functions well, you won't need global variables.
If I could just add, try to avoid using goto statements at this stage in your career - make use of proper loops and functions instead.
This is not a blanket rule, but goto's can be avoided unless there are very specific & valid reasons.
You could use loops like this:
bool Quit = false;
while(!Quit) {
// user wants to quit
Quit = true; // execution continues after end of while loop
}
Also make use of the toupper function, google "C++ toupper" so that you don't have to do 2 test on the value of the char.
If you can, avoid using namespace std as it pollutes the gloabal namespace which can cause conflict with function & variable names. For example the STL has all kinds of common words like distance, left & right etc which have special meaning. So either put std:: before each std thing, or do this for frequently used things:
using std::cout;
using std::cin;
using std::endl;
using std::string;
Some guys use std:: exclusivley, while I sometimes do a mixture of these two ideas.
Hope all goes well.