2017-01-17 2 views
0

Новое в программировании. Занятие классом в C. Ниже моя попытка программы, которая будет печатать «Какова ваша почасовая оплата?» затем прочитайте сумму в долларах и рассчитайте заработную плату. Затем напечатайте зарплату в форме: «Ваш общий доход за год составляет X долларов и Y центов.Как выделить центы с суммы в долларах.

Чтобы изолировать доллары от суммы доллара., Я усекал значение, преобразовывая в int из double. I не был уверен, как получить центов, поэтому я решил, что могу вычесть доллары из долларов. (100), и у меня будет число центов.

Я запускаю программу, и она отлично работает, за исключением того, что я не получаю сумму котировок, которую я ожидаю.

Если пользователь вводит 18.33 в качестве почасовой оплаты, тогда я получаю 31826 для общего доллара, 31836,40 для общего дохода. Но когда я их вычитаю и умножаю на 100, Мне дают 39 центов вместо 40.

int main(void) { 

double totalIncome  = 0.0; 
int totalDollars   = 0; 
int totalCents   = 0; 
double hourlyWage  = 0.0; 
int hoursPerWeek   = 40; 
const int WEEKS_PER_YEAR = 52; 

printf("What is your hourly wage? "); 
scanf("%lf", &hourlyWage); 

totalIncome = hourlyWage * hoursPerWeek * WEEKS_PER_YEAR; 
totalDollars = totalIncome; //converts to int from double 
totalCents = 10 * (totalIncome - totalDollars); 

printf("Your total income over a year is %d dollars and %d cents", totalDollars, totalCents); 

return 0; 

} 
+1

Если вы скомпилируете '-Wall', вы получите какие-либо предупреждения? Я думаю, что то, как вы назначаете totalCents, может привести к потере точности. Но я не уверен на 100%. Скомпилируйте этот флаг и проверьте. –

+0

Я придумал это решение для взлома ... totalCents = ((totalIncome + 0.005) - totalDollars) * 100; –

+0

Я не знаю, что вы имеете в виду -Wall Я новичок в этом –

ответ

3

Проблема заключается в том, что 100*(totalIncome - totalDollars) не точно 40, но 3.999999999941792e+01, таким образом, бросая его int доходности 39. Это хороший пример того, почему никогда не следует использовать с плавающей точкой для вычислений с валютами.

BTW: Вы можете просто избежать этой проблемы в целом, используя нечто вроде scanf("%d.%d", &hourlyDollars, &hourlyCents);

+0

Любить это решение, но если пользователь ставит 10, а не 10.00, что там будет? Будет ли это работать? –

+0

Да, на самом деле это будет просто читать 10 в «hourlyDollars». Однако это не может быть самым надежным решением для всех случаев, но ваше первоначальное решение также не выполняло никаких проверок. – cthl

-1

Одна из проблем в коде является то, что вы умножая центов на 10, а не 100.

Заменить totalCents = 10 * (totalIncome - totalDollars);

с

totalCents = 100 * (totalIncome - totalDollars);

У вас все еще будет небольшая неточность с плавающей запятой около цента.

+0

Г-н downvoter, позаботьтесь, чтобы объяснить – VHS

+1

Не знаю, я предполагаю, что проблема 'x 10' тангенциальна для основной проблемы неточности с плавающей запятой. Не беспокойтесь об этом - да, это расстраивает, но это не так плохо, как было в прошлом. Просто убедитесь, что вы хороший S.O. гражданин, и рано или поздно все хлопья исчезнут. –

+0

Спасибо VHS, я поймал это сам вскоре после этого. Даже не опечатка, просто плохая математика. o_O –

1

принять точку деньги всплывал с плавающей запятой центов до ближайшего целого числа, используйте round() или rint()

double x; 
double cents = rint(x * 100.0); 

принять точку деньги с плавающей до ближайшего целого числа центов, используйте lround() или llround()

long long cents = llround(x * 100.0); 

Чтобы взломать доллары FP на целые доллары и целые центы, масштаб, круглые, а затем отдельные.

double x; 
double cents = rint(x * 100.0); 
double cent = fmod(cents, 100.0); 
double dollar = (cents - cent)/100; 

Избегайте смешивания типов для поддержки денег. Используйте long long или double. У каждого есть свой short comings. Для ученических программ начинаются с широких целочисленных типов наименьшего номинала (цента).

Смежные вопросы