我正在学习Objective-C并完成了一个简单的程序并得到了意想不到的结果。这个程序只是一个乘法表测试...用户输入迭代次数(测试题),然后输入答案。在程序之后显示正确和错误答案的数量,百分比和接受/失败的结果。
#import <Foundation/Foundation.h>
int main(int argc,const char * argv []) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSLog(@"Welcome to multiplication table test");
int rightAnswers; //the sum of the right answers
int wrongAnswers; //the sum of wrong answers
int combinations; //the number of combinations@
NSLog(@"Please, input the number of test combinations");
scanf("%d",&combinations);
for(int i=0; i<combinations; ++i)
{
int firstInt=rand()%8+1;
int secondInt=rand()%8+1;
int result=firstInt*secondInt;
int answer;
NSLog(@"%d*%d=",firstInt,secondInt);
scanf("%d",&answer);
if(answer==result)
{
NSLog(@"Ok");
rightAnswers++;
}
else
{
NSLog(@"Error");
wrongAnswers++;
}
}
int percent=(100/combinations)*rightAnswers;
NSLog(@"Combinations passed: %d",combinations);
NSLog(@"Answered right: %d times",rightAnswers);
NSLog(@"Answered wrong: %d times",wrongAnswers);
NSLog(@"Completed %d percent",percent);
if(percent>=70)NSLog(@"accepted");
else
NSLog(@"failed");
[pool drain];
return 0;
}
问题(奇怪的结果)
当我输入3次迭代并回答它们时,我没有100%正确。只获得 99%。我在iPhone计算器上尝试的计数相同。
100/3 = 33.3333333 ...一个正确答案的百分比(程序显示33%。尾数被截断后的数字)
33.3333333 ... * 3 = 100%
有人可以解释我哪里出错了吗?感谢名单。
答案 0 :(得分:3)
Ints是整数。它们不能代表任意实数,如1/3。即使是可以表示实数的浮点数,也没有足够的精度来表示无限重复的十进制数,如100/3。您需要使用任意精度库,使用包含有理数作为数据类型的库,或者只需存储所需的精度并从那里进行舍入(例如,使您的整数单位为百分之一百分之一而不是一个百分点)。
答案 1 :(得分:3)
这是整数除法的结果。当您在两个整数类型之间执行除法时,结果将自动舍入为0以形成整数。因此,(100 / 3)
的整数除法得到33的结果,而不是33.33 ......当你将它乘以3时,你得到99.要解决这个问题,你可以通过改变100
来强制浮点除法。到100.0
。 .0
告诉编译器应该使用浮点类型而不是整数,强制浮点除法。因此,分割后不会进行舍入。但是,33.33 ...不能用二进制数表示。因此,您有时可能仍会看到不正确的结果。由于您将结果存储为整数,因此在乘法后仍会发生向下舍入,这将使其更加明显。如果要使用整数类型,则应在结果上使用round
函数:
int percent = round((100.0 / combinations) * rightAnswers);
这将导致数字在将其转换为整数类型之前四舍五入为最接近的整数。或者,您可以使用浮点存储类型并指定要显示的特定小数位数:
float percent = (100.0 / combinations) * rightAnswers;
NSLog(@"Completed %.1f percent",percent); // Display result with 1 decimal place
最后,由于浮点数学仍然会导致无法用二进制表示的数字的舍入,我建议在除以rightAnswers
之前乘以combinations
。这将增加结果可表示的机会。例如,100/3=33.33
...不可表示,将被舍入。如果先乘以3,则会得到300/3=100
,这是可表示的,不会被舍入。
答案 2 :(得分:2)
您可能希望实现某种舍入,因为33.333 ...... * 3 = 99.99999%。 3/10是无限小数,因此您需要进行某种舍入(可能在第3个小数位),以便答案正确。我会说if (num*1000 % 10 >= 5) num += .01
或沿着这些线的东西乘以100次移动十进制3次然后mod返回第三位数(可能为零)。一旦你总结了所有内容以避免错误,你也可能只想在最后进行舍入。
编辑:没有意识到你在最后使用整数数字让我失望,你可能想要使用double或float(浮点数稍微不准确,过去2或3位数,这可以用你想要的)。
答案 3 :(得分:0)
100/3是33.整数数学在这里。