2012-07-29 85 views
1

我對NSNumberFormatter有嚴重的爭議,甚至在閱讀了大量文檔後,我還沒有完全理解我遇到的一個非常簡單的問題。我希望你們能幫助我。NSNumberFormatter,NSDecimalNumber和Scientific Notation

我有什麼:一個NSDecimalNumber代表的計算結果,顯示在UITextField
我需要什麼:該結果的科學記數法。

我在做什麼:

-(void)setScientificNotationForTextField:(UITextField*)tf Text:(NSString*)text { 

NSString* textBefore = text; 

// use scientific notation, i.e. NSNumberFormatterScientificStyle 
NSNumberFormatter* formatter = [[NSNumberFormatter alloc] init]; 
//[formatter setGeneratesDecimalNumbers:YES]; 
[formatter setNumberStyle:NSNumberFormatterScientificStyle]; 
NSDecimalNumber* number = (NSDecimalNumber*)[formatter numberFromString:text]; 
tf.text = [number descriptionWithLocale:[[Utilities sharedUtilities] USLocale]]; 

NSString* textAfter = tf.text; 
// DEBUG 
NSLog(@"setScientificNotation | text before = %@, text after = %@", textBefore, textAfter); 

[formatter release]; 
} 

會發生什麼:
一個確定的結果可能是0.0099。 textBefore將保持正確的值。如果我不告訴格式化程序生成十進制數(在上面的代碼片段中註釋掉),它將從NSDecimalNumber創建一個NSNumber,它會創建一個錯誤結果,並將textAfter轉換爲0.009900000000000001--由於NSNumber的精度降低導致的舍入誤差通過NSDecimalNumber。
如果我確實告訴NumberFormatter生成小數,它仍然會產生錯誤的結果。另外,在它插入指數符號之前(例如「1.23456e-10」),它現在會生成(並顯示)完整的十進制數,這不是我想要的。
同樣,我想格式化程序使用NSDecimalNumber,因此它不會僞造結果,並且在必要時會有指數表示法。


我使用類錯了嗎?我誤解了文檔嗎?有人可以解釋爲什麼會發生這種情況,我可以如何創建我想要的行爲?如果我找到任何東西,我當然會繼續研究和更新。

回答

4

你不能只是投NSNumberNSDecimalNumber並期望它工作。如果您的號碼是不是太複雜,你可以溝NSNumberFormatter並嘗試使用這個:

NSDecimalNumber* number = [NSDecimalNumber decimalNumberWithString:text]; 

這會給你一個實際的例子NSDecimalNumber,其精確度。

不幸的是,setGeneratesDecimalNumbers:無法正常工作。這是一個known bug。 如果您的電話號碼太複雜,無法與decimalNumberWithString:配合使用,那麼您的Apple API可能不太合適。您唯一的選擇是手動將字符串解析爲NSDecimalNumber可以理解的內容或對NSNumberFormatter給出的不精確值進行一些後處理。最後,如果你真的想要一個科學記數法的數字,爲什麼不使用剛纔使用的數字格式化程序呢?只需撥打stringFromNumber:即可獲取格式化值。

+0

這是真的(我看過你的第一個版本的上述答案後)我應該使用stringFromNumber與NSDecimalNumber我從文本,而不是numberFromString獲得。我現在根據它們的長度來格式化字符串:如果太長時間無法放入文本字​​段,我正在應用科學記數法。目前它不能100%地工作,但我認爲它正在形成。感謝您的回答和鏈接;我有點希望它會是一個錯誤^^ – pille 2012-07-29 21:23:22