2010-02-25 116 views
3

如果我可能會提出兩個簡單的問題,那麼我應該如何處理兩個NSNumber對象,執行計算並最終得到一個也是NSNumber的結果?NSNumber計算和精度?

NSNumber *flux = [[NSNumber alloc] initWithDouble:100.0]; 
NSNumber *mass = [[NSNumber alloc] initWithDouble:3]; 

double intermediate = [flux doubleValue]/[mass doubleValue]; 
NSLog(@"INTER : %.20f", intermediate); 

NSNumber *result = [[NSNumber alloc] initWithDouble:intermediate]; 
NSLog(@"RESULT: %@", result); 

... 
... 

[flux release]; 
[mass release]; 
[result release]; 

另外從NSLog看在控制檯的結果,是否有任何精度損失?我會假設沒有,我所看到的只是顯示精度,但只是好奇?

INTER : 33.33333333333333570181 
RESULT: 33.33333333333334 

加里

回答

14

(切向你的問題,但相關的)

的NSNumber不打算做基10數學與。它主要用於包裝和存儲數值。如果你需要做真正的數學,你想用一個NSDecimal.

NSDecimalNumber,一個不變的子類的NSNumber的 ,提供了一個 面向對象的包裝做 基地10算術。一個實例可以 表示任何數量,可以是 表示爲尾數×10 ^指數 其中尾數是十進制整數高達 至38位長,和指數是從-128的整數 通過127

儘管我們稱他們爲「電腦」的事實,我們的邏輯引擎不能做真正的數學運算,所以他們必須僞造它。當你達到非常大或非常小的數量級的極端時,僞裝就開始顯現。這就是爲什麼你需要自定義的數字類,可以容納更多的信息,而不僅僅是一串數字。

因此,如果您對精度有任何疑問,請使用NSDecimal而不是NSNumber。 NSDecimal旨在執行精確的計算。

Edit01:

...我應該如何去取兩個 NSNumber對象,執行 計算,並以 結果也是一個NSNumber?

嚴格地說,你不應該使用NSNumber進行計算。你會注意到NSNumber沒有專門的數學方法。您必須轉換爲標量,然後再轉回到對象。這會導致精度損失,並且精度可能會根據硬件或標量的定義而改變。

NSDecimal通過對比可以精確地表示非常精確的數字,因爲它可以抽象地保存它們。它具有執行精確數學運算的專用方法。

也在尋找從NSLog的控制檯 的結果,是那裏 精度損失?

是的,除了格式化之外,還有數學精度的損失。標量具有不同的精度,這取決於它們存儲的數量和類型的大小。在大數量級上,這會導致精度問題。如果你混合使用類型,比如說一個NSInteger和一個NSUInteger,你會得到NSInteger的最大精度。

也碰到所有old problems of using scalars.

如果您使用的是不能持有 的價值,你回來的錯誤 結果 - 例如,一個類型要求其 值一個NSNumber對象,如果你請求用 double創建的數字的浮點值大於FLT_MAX, 或使用比最大值大於 的浮點數創建的數字 的整數值大於NSInteger的最大值。

NSDecimal讓你擺脫所有這些可能的錯誤來源。它以精確的數學計算達到超出任何人在現實世界中使用的程度。

我重複一遍:如果精度是一個問題,請不要使用NSNumber或標量。

+0

我相信你誤解了這個問題。 – 2010-02-25 12:32:29

+0

更像是我在一條正切線上。我編輯澄清。 – TechZen 2010-02-25 12:36:57

+0

謝謝,很高興知道NSDecimal,我會看看。 – fuzzygoat 2010-02-25 13:48:34

2

使用%@意味着NSLog將發送description方法的參數,並且將使用其描述在輸出中。不管NSNumber決定是否足夠精確的描述是你會在NSLog看到的數字。如果你做了:

NSLog ("%.20f", [result doubleValue]); 

應該產生的輸出爲NSLogintermediate相同。

+0

雖然我無法測試,但我只是在這裏猜測。 – dreamlax 2010-02-25 12:07:06

0

NSNumbers和其他NSValues只是原始值周圍的對象包裝。該對象將包含您放入它的任何內容,具體取決於您是如何創建它的。