2012-01-05 14 views
6
NSLog(@"%llu\n\n", ULONG_LONG_MAX); 

NSDecimalNumber *decimal = [NSDecimalNumber decimalNumberWithString:@"154550038129946620"]; 
NSLog(@"%@", decimal); 
NSLog(@"%llu\n\n", [decimal unsignedLongLongValue]); 

decimal = [NSDecimalNumber decimalNumberWithString:@"154550038129946628"]; 
NSLog(@"%@", decimal); 
NSLog(@"%llu", [decimal unsignedLongLongValue]); 

這兩個值都小於ULONG_LONG_MAX。但是,我們在輸出中看到的是:客觀C奇數十進制長轉換

2012-01-05 17:41:55.879 test[1276:207] 18446744073709551615 

2012-01-05 17:41:55.969 test[1276:207] 154550038129946620 
2012-01-05 17:41:56.095 test[1276:207] 154550038129946624 

2012-01-05 17:41:56.096 test[1276:207] 154550038129946628 
2012-01-05 17:41:56.096 test[1276:207] 154550038129946624 

我在做什麼錯了?我不知道如何解釋這種行爲。

回答

5

NSDecimalNumber缺少unsignedLongLongValue方法,所以它繼承了NSNumber的默認實現。獲得NSDecimalNumber價值的唯一方法是獲得NSDecimal結構或double。轉換錯誤是在將NSDecimalNumber轉換爲double的過程中引入的。

+0

我沒有從一開始就得到它,併發布了我自己的答案,但現在我明白了,並且您的答案與我的答案相同。對於其他人,就像我一樣,他們並沒有完全理解 - 在鑄造爲無符號long long之前,「NSDecimalNumber」中的小數點數將翻倍。無論如何,我認爲這是基本的SDK錯誤。 – 2012-01-05 16:13:35

+0

@AlexanderN。我不同意這是一個基本的軟件開發工具包的缺點:如果你留在'NSDecimalNumber's中,你會得到可靠的精度,這對於SDK的設計者來說很重要。轉換到其他類型僅僅是爲了方便;他們的使用伴隨着理解,由於表示的不同,可能會丟失一些精度。 – dasblinkenlight 2012-01-05 16:23:26

+0

我想不起來。但你不覺得這有點奇怪 - 在整數長整型(在這種情況下)小數整數長整型並失去精度,就像在float-int鑄造中一樣? – 2012-01-05 16:28:41