2012-07-29 40 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