鄙人不才,此中鄙陋甚多,望海涵!
题目描述
读取一个带有两个小数位的浮点数,这代表货币价值。
在此之后,将该值分解为多种钞票与硬币的和,每种面值的钞票和硬币使用数量不限,要求使用的钞票和硬币的数量尽可能少。
钞票的面值是100,50,20,10,5,2。
硬币的面值是1,0.50,0.25,0.10,0.05和0.01。
输入格式
输入一个浮点数N。
输出格式
参照输出样例,输出每种面值的钞票和硬币的需求数量。
数据范围
0≤N≤1000000.00
样例
输入样例:
576.73
输出样例:
NOTAS:
5 nota(s) de R$ 100.00
1 nota(s) de R$ 50.00
1 nota(s) de R$ 20.00
0 nota(s) de R$ 10.00
1 nota(s) de R$ 5.00
0 nota(s) de R$ 2.00
MOEDAS:
1 moeda(s) de R$ 1.00
1 moeda(s) de R$ 0.50
0 moeda(s) de R$ 0.25
2 moeda(s) de R$ 0.10
0 moeda(s) de R$ 0.05
3 moeda(s) de R$ 0.01
C++ 代码
#include<iostream>
using namespace std;
const int N=10;
int b[N],c[N];
int main()
{
double s[7]={0,100,50,20,10,5,2};
double p[7]={0,1.00,0.50,0.25,0.10,0.05,0.010};
double a;
cin>>a;
for(int i=1;i<=6;i++)
{
b[i]=a/s[i];
a-=(s[i]*b[i]);
}
for(int i=1;i<=6;i++)
{
double x=a/p[i];
c[i]=(int)(x+0.00001);//防止了精度问题
a=a-(c[i]*p[i]);
}
puts("NOTAS:");
for(int i=1;i<=6;i++)
{
printf("%d nota(s) de R$ %.2lf\n",b[i],s[i]);
}
puts("MOEDAS:");
for(int i=1;i<=6;i++)
{
printf("%d moeda(s) de R$ %.2lf\n",c[i],p[i]);
}
return 0;
}
为什么要加0.00001呢,而不是0.000001,好蒙
xd为什么加了0.00001就能避免double精度的问题了啊
因为double除法的保留位数问题导致精度丢失
你这里的精度丢失如果从底层来考虑的话是因为浮点数的表示所导致的,其实已开始定义的浮点数就是一个近似值,0.01实际是0.010000000000012这样的数,但是如果用减法的话会导致最后我们看到的n显示是0.01但是他实际是一个近似0.01的一个数,但比0.01小,因为定义的比所显示的大所以你加上0.00001就解决了这个问题,这样可以使原来不够除的数够除了
??????????
可以尝试printf一下最后剩下的结果,我尝试确实是0.0100000XX这样的数字。
https://www.acwing.com/solution/content/129051/
精度损失从根本上来看是二进制的先天不足,小数部分对于某些数无法做到精确表达。比如2的负一次方是0.5,负二次方是0.25,负三次方是0.125。二进制只能无限接近0.8。而最后几位二进制位,又因为空间有限 和做除法时(小数点左移)增加的比特位,被挤了出去,所以造成精度损失。如果小数部分能精确表达,后几位出去与否,是不会影响结果的。
大佬太谦虚了!
=_=
超总 nb!!、
那我必是菜鸡!
兄弟,你逗号打错了
太激动了!hh
大佬大佬