c++一道与浮点数有关的题目 不知为何不能通过 求大神打救 谢谢
# include<iostream>
# include<iomanip>
using namespace std;
int main()
{
float a,b,sum;
while (cin >> a >> b && (a||b))
{
if (a>=0) a = int(a*100+0.5)/100.0;
if (a<0) a = int(a*100)/100.0;
b = int(b*100)/100.0;
sum =a - b;
cout << sum << endl;
}
return 0;
} 展开
哪里的题,有OJ吗?
四舍五入的时候最好乘到1000去
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double a,b,sum;
while (cin >> a >> b && (a||b))
{
if (a>=0) a = int(a*1000 + 5) / 10 /100.0;
if (a<0) a = int(a*100)/100.0;
b = int(b*100)/100.0;
sum =a - b;
cout << sum << endl;
}
return 0;
}
问题出在哪里 是float强制保留多少位小数吗
感觉都一样,有评测平台?
//以下是我前几天回答这个题目时的答案。
#include <stdio.h>
#include <math.h>
#include <string.h>
int main() {
int sign,size;
char format[20];
double a,b,eps = 1E-6;
printf("输入两个数( 0 0 to quit):");
while(scanf("%lf%lf",&a,&b) == 2) {
if(fabs(a) <= eps && fabs(b) <= eps)
break;
if(a < 0) {
a = -a;
sign = -1;
}
else sign = 1;
a = sign * ((int)(100 * a + 0.5))/100.0;
if(b < 0) {
b = -b;
sign = -1;
}
else sign = 1;
b = sign * int(100 * b)/100.0;
a -= b;
sprintf(format,"%lf",a);
size = strlen(format);
while(format[size - 1] == '0') {
format[size - 1] = 0;
--size;
}
if(format[size - 1] == '.')
format[size - 1] = 0;
printf("A - B = %s\n",format);
printf("\n输入两个数( 0 0 to quit):");
}
return 0;
}
谢了 代码我有 我想知道我哪里错了
你的代码无法保证不输出多余的0,也不能保证无小数时,也不输出小数点。
我看主要逻辑无错,恐怕问题出在while (cin >> a >> b && (a||b))中。当输入不是数字时因cin >> a >> b失败而循环就结束,对此问题代码没有防止和处理措施。其他逻辑我认为是正确的。不过有个问题要注意,直接对第三位小数处理就有个精度误差问题,比如b输入22.3时,你这样处理完会得来22.29来——这是存储误差造成的,会不会是这些造成不通过?你改成如下试试——
int main(void){
float a=1.0,b;
cout << "Input 2 real Numbers...\n";
while(a||b){
if(cin >> a >> b){
if(a>=0) a = int(a*100+0.5)/100.0;
if(a<0) a = int((a-1E-6)*100)/100.0;
b = b>0 ? b+1E-6 : b-1E-6;//加上这一句以改善浮点数的存储误差
b = int(b*100)/100.0;
cout << a-b << endl;
}
else{//处理输入错误
cout << "Error! Please input number...\n";
fflush(stdin);
cin.clear();
}
}
return 0;
}
所有样例都是数字 我将float改为double后就行了 不懂
double型是64位二进制表示的浮点数,而float是32位的,精度太低,误差大,就造成错误。我上面已说过了,你原来的代码输入55.44567和22.3,在float下会把22.3处理成22.29,这样55.45-22.29不就成了33.16了?这不就错了?本应是33.15啊!而在double下,由于精度高,22.3处理后还是22.3,所以就对了。你可以这样验证:在你的代码中的b = int(b*100)/100.0;后加一句cout 0 ? b+1E-6 : b-1E-6;这一句就是为了改善float的存储误差,因为浮点数的尾数是用原码表示的,一般都不足标称的数,加一个很小的正数略有超过,但并不影响精度。这样就解决了在float下正确处理的问题。
这道题应该用整数减法,按整数部分和小数部分区分开来。无论float,double都会有问题。 比如输入1.235 1.234,按规则,应该是1.24 - 1.23 = 0.01,但你按float存储,本身就有一个精度逼近的问题,由此会有误差,导致结果是0.00999999(float精度存储有限,精度差,是对数字的逼近,因此换成精度高的double,这个文件解决);但即便是double,输入111111.111 - 222.22 = 110888.89,按你的算法,由于依靠cout输出float,导致结果是110889,double也没有。--虽然你通过了OJ。
用字符串,或大数据的方法也是可行的,但考虑这题要求的精度其实只是小数后2位,因此还是可以用相对简洁的代码去实现的。
下面的代码按整数作减法,然后整数和小数部分区分输出,即便是用float也没有问题:
① 代码
#include <iostream>
using namespace std;
int main(int argc, char const *argv[])
{
float a, b;
long a1, b1, int_part, frac_part;
while (cin >> a >> b && (a||b))
{
a1 = int(a*100);
if (a > 0) {
int third = (int(a*1000)) % 10;
if (third >= 5) a1 ++;
}
b1 = int(b*100);
int_part = (a1 - b1) / 100;
frac_part = (a1-b1) - 100 * int_part;
cout << int_part;
if (frac_part !=0) cout << "." << frac_part;
cout << endl;
}
return 0;
}
② 结果:
1.234 1.234
0
1.235 1.234
0.1
-1.235 -1.234
0
111111.111 222.22
110888.89
0 0