Objective-C:奇怪的计算结果

时间:2011-07-12 00:01:48

标签: objective-c

我正在学习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%

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

4 个答案:

答案 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.整数数学在这里。