我与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
将保持正确的价值。如果我不告诉格式化程序生成十进制数(在上面的代码片段中注释掉),它将从NSDecimalNumber创建一个NSNumber,它会创建一个错误的结果并将textAfter
变成0.009900000000000001 - 一个舍入错误到期与NSDecimalNumber相比NSNumber的精度降低。
如果我告诉NumberFormatter生成小数,它仍然会创建错误的结果。更重要的是,在它插入指数表示法之前(例如" 1.23456e-10"),它现在会生成(并因此显示)完整的十进制数,这不是我的意思想。
同样,我希望格式化程序使用NSDecimalNumber,这样它就不会伪造结果,并在必要时使用指数表示法。
我使用的课错了吗?我误解了文档吗?有人可以解释为什么会发生这种情况以及如何创建我想要的行为?如果我找到任何东西,我当然会继续研究和更新。
答案 0 :(得分:4)
您不能只将NSNumber
投射到NSDecimalNumber
并期望它能够正常运行。如果您的号码不是太复杂,您可以放弃NSNumberFormatter
并尝试使用此号码:
NSDecimalNumber* number = [NSDecimalNumber decimalNumberWithString:text];
这将为您提供一个具有精确度的实际NSDecimalNumber
实例。
不幸的是,setGeneratesDecimalNumbers:
无效。这是一个known bug。
如果您的号码太复杂而无法与decimalNumberWithString:
一起使用,那么您可能会对Apple的API不满意。您唯一的选择是手动将字符串解析为NSDecimalNumber
可以理解的内容,或者对NSNumberFormatter
给您的不精确值进行一些后处理。
最后,如果你真的想要一个科学记数字,为什么不使用你刚刚使用的数字格式器?只需致电stringFromNumber:
即可获取格式化值。