2012-12-01 23 views
0

時發出按鈕方的mainLabel的價值,我使用錯誤的結果平方值

- (IBAction)squarePressed:(id)sender 
{ 

    NSString *mainLabelString = mainLabel.text; 

    int mainLabelValue = [mainLabelString intValue]; 

    NSString *calculatedValue = [NSString stringWithFormat: @"%d", mainLabelValue*mainLabelValue]; 

    mainLabel.text = calculatedValue; 

} 

沒有誤差修改顯示,它與小的數字效果很好,
例如,結果平方720是正確的,518400,但如果我試圖平方那個數字,而不是268738560000,我得到-1844379648。
這是怎麼發生的?

+1

在方法內的所有行之前放置4個空格。 –

回答

1

這是一個數字溢出,如果要使用最大數量的位來避免溢出,請使用long long。同樣,long double會很好,但不是那麼精確。

- (IBAction)squarePressed:(id)sender 
{ 

    NSString *mainLabelString = mainLabel.text; 

    long long mainLabelValue = [mainLabelString longLongValue]; 

    NSString *calculatedValue = [NSString stringWithFormat: @"%lld", mainLabelValue*mainLabelValue]; 

    mainLabel.text = calculatedValue; 

} 

當然,如果你使用的高數字也這樣,可能發生溢出,但它依賴於從int長長整型的位相差發生了更高的價值。

+0

_Buffer_溢出?不太可能。算術溢出 - 是的。 – driis

+0

當然,這只是一個錯誤,我不是指緩衝區溢出。現在我編輯了這個詞。 –

4

int是一個有符號的32位數字。

518400平方的結果不適合32位,所以計算溢出,這就是爲什麼你會看到大的負值。

嘗試使用long,這是64個比特,並且應該足以滿足該號碼:

long mainLabelValue = [mainLabelString longLongValue]; 
+5

而且,由於所有方塊都是正整數,因此請使用'unsigned long'並獲得兩倍的可用範圍。 – ikuramedia

+0

@driis我可以用long替換項目中的所有int值嗎? –

+0

當然,如果該數據類型適合您的數據。 – driis

3

你可能溢出的最大整數的大小,因此,負開關。對於32位系統,這個值是2,147,483,647(2^31-1)

4

int可能是一個32位的數字,並且518400的平方大於可以用32位表示。其中一些解釋在When to use NSInteger vs. int

你可以寫

NSInteger mainLabelValue = [mainLabelString longValue]; // or long mainLabelValue... 
NSString *calculatedValue = [NSString stringWithFormat: @"%ld", mainLabelValue*mainLabelValue]; 

NSInteger的似乎是在iOS版64位。