2011-07-12 83 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整數數學。