2011-07-12 86 views
0

我学习Objective-C和已经完成了一个简单的程序,并得到了一个意想不到的结果。这个程序只是一个乘法表测试...用户输入迭代次数(测试问题),然后输入答案。程序显示正确和错误答案的数量,百分比和接受/失败的结果。的Objective-C:奇怪的计算结果

#import <Foundation/Foundation.h> 

INT主(INT的argc,常量字符* 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 [email protected] 


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%

可有人解释我哪里出错了?感谢名单。

+2

这似乎与您的问题没有关系,但您需要初始化您的变量。如果在代码开始时'rightAnswers'和'wrongAnswers'确实为0,那么这是一个令人高兴的巧合,而不是一个有保证的事实。 – Chuck

+0

不帮忙!它仍然是99%。在我的早期版本中,它们已初始化。 – NCFUSN

+0

是的,我没有想到它会有所帮助。我只是警告你避免将来出现问题,因为依赖这种未定义的行为是使程序最终爆发的好方法。你得到99的原因在下面的答案中解释。 – Chuck

回答

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,这是可表示的,不会被舍入。

+0

非常感谢。伙计们,我很高兴你的存在... – NCFUSN

2

你可能想实现某种形式的舍入,因为33.333 .... * 3 = 99.99999%的。 3/10是一个无限小数,因此您需要进行某种舍入(可能在小数点后三位),以便答案正确。我会说if (num*1000 % 10 >= 5) num += .01或东西沿着这些线路乘100继续小数3次,然后用mod的第三个数字(可能是零)。一旦你总结了所有事情以避免错误,你也可能只想在最后回合。 编辑:没有意识到你在最后使用整数数字把我扔掉了,你可能想要使用双精度浮点数或浮点数(浮点数在过去的2或3个数字上稍微不准确,这与你想要的是一致的)。

+0

我试图将变量定义为浮点数,但它使得更加混乱。 – NCFUSN

+0

你是什么意思更混乱? –

3

int为整数。它们不能代表像1/3的任意实数。即使浮点数可以代表实数,也不会有足够的精度来表示像100/3这样的无限重复小数。您可能需要使用任意精度库,使用包含有理数据库的库作为数据类型,或者只需存储尽可能多的精度,然后从中循环(例如,使整数单位为百分之一百分之一而不是一个百分点)。

0

100/3是这里33整数数学。