繁体   English   中英

while 循环中的 C++ 浮点精度

[英]C++ floating point accuracy in while loops

我试图通过使用一系列 while 循环来计算总计中美元和硬币面额的数量。 然而,当我深入到硬币上时,我差了一分钱。 当我输入 99.95 时,我会得到 3 个四分之三、1 角钱、1 镍和 4 便士的输出。 我已将问题缩小到浮点精度问题。 但是,我研究过的所有解决方案都不适用于我的情况。 任何指针?

#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;
}

在需要精确值的情况下不要使用浮点数。 99.95 不能用浮点数或双精度数精确表示,有点像 1/3 不能用有限数量的正常十进制数字精确表示。

正如 Doug T. 所建议的,您可以使用一个整数来表示便士的数量。 当用户键入 123.45 时,将其读为两个整数,然后将其存储为 12345 便士,而不是 123.45 美元。

在这种情况下,您还可以尝试将上次while (amount >= .01)更改为while (amount >= .005) 这不是一个普遍推荐的解决方案,如果这是一个真实的银行应用程序,你真的应该避免它,但它至少有助于防止一些错误。

在这种情况下,您应该使用定点值,而不是浮点值。

尽管人们以美元来看待金钱,这并不准确,但金钱以美分来衡量,这是准确的。 只需计算美分的数量,除以 100 即可获得美元金额,并取模数即可获得美分金额。 在这种情况下,浮点不是合适的工具。

二进制浮点数通常不能表示小数部分,即使小数总数很小。 例如,无法准确表示0.1

为了处理精确值,存在不同的方法,这些方法都相当于使用与2不同的基数。 根据 tge 的特定需求,这些方法或多或少涉及。 对于您的情况,最简单的方法是使用固定精度而不是可变精度。 要以固定精度进行计算,您只需使用一个整数来表示您实际想要的值乘以合适的10幂。 根据您执行的计算量,您可以将逻辑打包到一个类中或将其分发到整个代码中。 在“真正的”应用程序中,我会将它打包到一个类中,在作业(家庭作业、面试等)中,我可能只是将逻辑直接应用于int

这是固定代码,我使用了 TJD 的建议,而不是使用 .01,而是使用了 .0099。 对于我的问题似乎有效,谢谢大家!

    #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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM