NSNumberFormatter、NSDecimalNumber 和科学记数法
Posted
技术标签:
【中文标题】NSNumberFormatter、NSDecimalNumber 和科学记数法【英文标题】:NSNumberFormatter, NSDecimalNumber and Scientific Notation 【发布时间】:2012-07-29 19:46:27 【问题描述】:我与 NSNumberFormatter 发生了严重的争议,即使在阅读了它的大量文档之后,我也无法完全解决我遇到的一个非常简单的问题。希望大家能帮帮我。
我有什么:一个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
将保持正确的值。如果我不告诉格式化程序生成十进制数(在上面的 sn-p 中注释掉),它将从 NSDecimalNumber 创建一个 NSNumber,这会创建一个错误的结果并将 textAfter
转换为 0.009900000000000001 - 由于NSNumber 在 NSDecimalNumber 上的精度降低。
如果我告诉 NumberFormatter 生成小数,它仍然会产生错误的结果。更重要的是,在它插入指数符号(例如“1.23456e-10”)之前,它现在会生成(并因此显示)完整的十进制数,这不是我想要的。
再次,我想让格式化程序使用 NSDecimalNumber,这样它就不会伪造结果,并且在必要时使用指数表示法。
我是否使用错误的课程?我是否误解了文档?有人可以解释为什么会发生这种情况以及如何创建我想要的行为吗?如果我发现任何东西,我当然会继续研究和更新。
【问题讨论】:
【参考方案1】:您不能只是将NSNumber
转换为NSDecimalNumber
并期望它能够工作。如果您的号码不是太复杂,您可以放弃NSNumberFormatter
并尝试使用它:
NSDecimalNumber* number = [NSDecimalNumber decimalNumberWithString:text];
这将为您提供一个实际的 NSDecimalNumber
实例,并具有其精度。
很遗憾,setGeneratesDecimalNumbers:
无法正常工作。这是known bug。
如果您的号码太复杂而无法使用 decimalNumberWithString:
,那么您可能对 Apple 的 API 不走运。您唯一的选择是将字符串手动解析为 NSDecimalNumber
可以理解的内容,或者对 NSNumberFormatter
提供给您的不精确值执行一些后处理。
最后,如果你真的想要一个科学计数法的数字,为什么不直接使用你刚刚使用的数字格式化程序呢?只需调用stringFromNumber:
即可获取格式化值。
【讨论】:
确实(我在查看上述答案的第一个版本后意识到)我应该将 stringFromNumber 与我从文本中获得的 NSDecimalNumber 一起使用,而不是 numberFromString。我现在根据字符串的长度格式化字符串:如果太长而无法放入文本字段,我将应用科学记数法。它现在不是 100% 有效,但我认为它正在形成。感谢您的回答和链接;我有点希望它是一个错误^^以上是关于NSNumberFormatter、NSDecimalNumber 和科学记数法的主要内容,如果未能解决你的问题,请参考以下文章
NSNumberFormatter - 获取货币代码的货币符号
NSNumberFormatter、NSDecimalNumber 和科学记数法
使用 NSNumberFormatter 循环中的 Objective C 自动释放