Подразделение с плавающей точкой, этаж и когда простая программа C ++ Change Computing становится сложной

Деление с плавающей запятой приводит к тому, что значение, равное 1, должно быть 0,99999999, таким образом, в качестве основания используется значение 0 вместо 1, поэтому расчет требуемого изменения является неправильным.
Какой самый простой способ справиться с этим? (Также, если есть какое-то руководство / статья о том, как с этим бороться, я бы хотел ссылку для справки.)
Ex. 3.51 сломан.

Обе версии кода имеют одинаковую проблему.

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
//3.51 is broken due to floating point issue of .999999999 instead of 1. Work around?
int main(int argc, char *argv[])
{
const float DOLLARVALUE=1.0;
const float QUARTERVALUE=0.25;
const float DIMEVALUE=0.10;
const float NICKELVALUE=0.05;
const float PENNIEVALUE=0.01;
const int CELLWIDTH=12;
float totalChange=0;
int countDollars=0;
int countQuarters=0;
int countDimes=0;
int countNickels=0;
int countPennies=0;
float remainingTotal=0;cout<<"Please insert total amount of change needed: ";
cin>>totalChange;
cout<<endl;

remainingTotal=totalChange;countDollars=(remainingTotal/DOLLARVALUE);
remainingTotal=(remainingTotal-(countDollars*DOLLARVALUE));

countQuarters=(remainingTotal/QUARTERVALUE);
remainingTotal=(remainingTotal-(countQuarters*QUARTERVALUE));

countDimes=(remainingTotal/DIMEVALUE);
remainingTotal=(remainingTotal-(countDimes*DIMEVALUE));

countNickels=(remainingTotal/NICKELVALUE);
remainingTotal=(remainingTotal-(countNickels*NICKELVALUE));

countPennies=(remainingTotal/PENNIEVALUE);
remainingTotal=(remainingTotal-(countPennies*PENNIEVALUE));
//cout<<fixed<<setprecision(0);
cout<<"This amount can be given in change by:";
cout<<endl;
cout<<endl;

cout<<"Dollars"<<setw(CELLWIDTH)<<"Quarters";
cout<<setw(CELLWIDTH)<<"Dimes"<<setw(CELLWIDTH)<<"Nickles";
cout<<setw(CELLWIDTH)<<"Pennies";
cout<<endl;
cout<<"------------------------------------------------------";
cout<<endl;

cout<<setw(4)<<countDollars;
cout<<setw(CELLWIDTH)<<countQuarters;
cout<<setw(CELLWIDTH)<<countDimes;
cout<<setw(CELLWIDTH)<<countNickels;
cout<<setw(CELLWIDTH)<<countPennies;

cout<<endl;
cout<<endl;

return 0;
}

Следующая версия имеет те же проблемы в более явном виде.

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
//3.51 is broken due to floating point issue of .999999999 instead of 1. Work around?
int main(int argc, char *argv[])
{
const float DOLLARVALUE=1.0;
const float QUARTERVALUE=0.25;
const float DIMEVALUE=0.10;
const float NICKELVALUE=0.05;
const float PENNIEVALUE=0.01;
const int CELLWIDTH=12;
float totalChange=0;
float countDollars=0;
float countQuarters=0;
float countDimes=0;
float countNickels=0;
float countPennies=0;
float remainingTotal=0;cout<<"Please insert total amount of change needed: ";
cin>>totalChange;
cout<<endl;

remainingTotal=totalChange;countDollars=floor(remainingTotal/DOLLARVALUE);
remainingTotal=(remainingTotal-(countDollars*DOLLARVALUE));countQuarters=floor(remainingTotal/QUARTERVALUE);
remainingTotal=(remainingTotal-(countQuarters*QUARTERVALUE));

countDimes=floor(remainingTotal/DIMEVALUE);
remainingTotal=(remainingTotal-(countDimes*DIMEVALUE));

countNickels=floor(remainingTotal/NICKELVALUE);
remainingTotal=(remainingTotal-(countNickels*NICKELVALUE));

countPennies=floor(remainingTotal/PENNIEVALUE);
remainingTotal=(remainingTotal-(countPennies*PENNIEVALUE));

cout<<"Amount of change needed is: "<<totalChange;
cout<<endl;
cout<<endl;
//cout<<fixed<<setprecision(0);
cout<<"This amount can be given in change by:";
cout<<endl;
cout<<endl;

cout<<"Dollars"<<setw(CELLWIDTH)<<"Quarters";
cout<<setw(CELLWIDTH)<<"Dimes"<<setw(CELLWIDTH)<<"Nickles";
cout<<setw(CELLWIDTH)<<"Pennies";
cout<<endl;
cout<<"------------------------------------------------------";
cout<<endl;cout<<setw(4)<<countDollars;
cout<<setw(CELLWIDTH)<<countQuarters;
cout<<setw(CELLWIDTH)<<countDimes;
cout<<setw(CELLWIDTH)<<countNickels;
cout<<setw(CELLWIDTH)<<countPennies;

cout<<endl;
cout<<endl;

return 0;
}

Есть ли простой обходной путь для этого? Я открыт для всех идей.

0

Решение

Есть несколько способов легко это исправить:

  1. Используйте целые или рациональные числа вместо чисел с плавающей точкой.

  2. Используйте округление вместо усечения, где это применимо.
    Вы можете реализовать round(x) просто как floor(x + 0.5),
    Не особенно подходит в вашем случае, но прямо ведет к следующему.

  3. Вы можете округлить с точностью до десятичного знака и затем пол. Скажем, вы хотите получить значение ниже 0,9999 до 0, но 0,9999 или что-то более высокое должно быть равно 1. Тогда все, что вам нужно, это использовать floor(x + 0.0001) вместо floor(x),

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]