试图回合数字时如何避免丧失精度?(C )
how to avoid the loss of precision when trying to round number? (C++)
刚完成了我的C 的第一周(使用Visual Studio 2017),我写了一个程序,向用户询问资金量,并将打印账单和硬币的数量。它在开始时起作用,但有时只是打印错误的数字。(当用户输入$ 1.28时,它显示1美元,1季度和2便士。)这是我的代码,有什么错吗?算法或数据类型?
#include<iostream>
using namespace std;
float Q = 0.25;
float D = 0.10;
float N = 0.05;
float P = 0.01;
float Dollar = 1;
float money;
float dollars, quarters, dimes, nickels, pennies;
int main() //to break money into coins.
{
cout << "how many money do u have?" << endl;
cin >> money;
dollars = (int)money;
quarters = (int)((money - dollars*Dollar)/Q);
dimes = (int)((money - dollars*Dollar - quarters*Q) / D);
nickels = (int)((money - dollars*Dollar - quarters*Q - dimes*D) / N);
pennies = (int)((money - dollars*Dollar - quarters*Q - dimes*D - nickels*N) / P);
cout << "$" << money << " can be break into :" << endl;
cout << dollars << " dollars. " << endl;
cout << quarters << " quarters. " << endl;
cout << dimes << " dimes. " << endl;
cout << nickels << " nickels. " << endl;
cout << pennies << " pennies. " << endl;
}
试图回合数字时如何避免丧失精度?(C )
当您从浮点转换为整数时,分数部分会截断。为了确保整数精度损失(获取正确的"整体"),每次将结果添加为0.5,例如:
quarters = static_cast<int>(((money - dollars*Dollar)/Q)+0.5);
但是,当结果为负面时,这无效,例如:50.5-100 = -49.5-> 1 = -48.5-> -48 ...不是49
对于负面因素,您需要减去0.5。
我想,在行中
pennies = (int)((money - dollars*Dollar - quarters*Q - dimes*D - nickels*N) / P);
零件(money - dollars*Dollar - quarters*Q - dimes*D - nickels*N)
将产生一个值,而不是完全.03
,而是下面的一个值。这是由于浮点算术的性质,您应该对此进行阅读。鉴于它是.029999999995
之类的,因此除以0.01不会产生3.0,但也许不会产生2.9999999995
。由于您没有四舍五入,而是将价值投放到整数,因此该期间后的整个部分将被扔掉,因此会导致2便士。
您如何解决此问题?
最简单的是要绕过值而不是施放值,这应该产生正确的价值,但这是对问题的刺激性解决方案。您也可以尝试使用double
而不是float
,但这也无法解决问题。您可能会得到正确的,但是
存储整个便士
您可以将全部数量存储为整数(整个便士)
int amountInPennies;
int penniesPerDollar = 100;
int penniesPerQuarter = 25;
int penniesPerDime = 10;
int penniesPerNickle = 5;
int totalDollars = amountPennies / penniesPerDollar;
int totalQuarters = (amountPennies - totalDollars * penniesPerDollar) / penniesPerQuarter;
...
小数类型
在处理金钱的现实世界应用中(嗯,取决于类型),您很可能会使用某种小数类型而不是float
。根据此答案,有gnu许可下的算术算术的库。您仍然可以滚动自己的十进制类型,即或多或少地做我在第一种方法中所介绍的事情。这可能是一个很好的学习,但是当涉及现实世界应用时,现成的库可能是更好的选择。
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 正在将csv文件读取为双精度矢量
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 我可以信任表示整数的浮点或双精度来保持精度吗
- 如何在C++中的同一函数中使用字符串和双精度
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 当使用比格式支持的精度更高的精度来显示数字时,会写出什么数据
- 如何计算具有指定类型的表达式的相对精度和绝对精度
- 如何打印boost多精度128位无符号整数
- 检查是否以特定精度给出双精度
- 转换函数,将 std::数组的双精度作为参数或双精度作为参数单独转换
- C 字符串返回字符串的整数/双精度/长整型值
- 为什么将双精度转换为 int 似乎在第 16 位数字之后将其四舍五入?
- 如何使双精度值的 C++ 和 C# 中的结果相同
- 使用浮点数和双精度数的非常小数字的数学
- 使用 Xcode 将双精度存储在数组C++中
- 为什么输出精度没有正确舍入?
- 当将变量作为函数参数传递时,由于隐式铸造而导致的精度丧失
- 试图回合数字时如何避免丧失精度?(C )