10

根据文档,[NSDecimalNumber decimalNumberWithString:]应使用语言环境小数分隔符:

NSDecimalSeparator 是句点(例如在美国使用)还是逗号(例如在法国使用)取决于默认语言环境。

但是当我尝试时,这段代码:

NSLog(@"%@", [NSDecimalNumber decimalNumberWithString:@"100,1"]);
NSLog(@"%@", [NSDecimalNumber decimalNumberWithString:@"100,1" locale:NSLocale.currentLocale]);

给...

100
100.1

...作为 iOS 5 和 iOS 6 上的输出。我尝试使用瑞典语和法语作为区域设置,因为这两个国家/地区都使用逗号 (,) 作为小数分隔符。

输出不应该相同吗?

(我知道我可以使用 [NSDecimalNumber decimalNumberWithString:locale:] 来强制行为,所以这个问题不是关于寻找替代方案,只要这是一个错误或者我做错了什么)

4

1 回答 1

7

NSDecimalNumber 只是数字类型数据的存储类。它在你传递给它的字符串上运行一个解析器(NSNumberFormatter)来创建它的数字。您的第二个日志语句“更好”工作的原因是因为第一个使用默认数字格式语言环境(它看起来像en_US,但我无法验证这一点,请参阅编辑打击以获取更多信息。)进行解析,并且“100,1”不是有效数字,因此“非数字”部分被剥离。通过指定使用“,”小数分隔符的语言环境,它可以正确捕获完整的数字。

当你 NSLog() 一个 NSDecimalNumber 时,它只是简单地调用-description,它没有语言环境上下文并且可以或多或少地打印它想要的任何东西。

如果要打印格式正确的数字,请使用 NSNumberFormatter,如下所示:

NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:@"100.1"];

NSLog(@"%@", number);

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];

[formatter setNumberStyle:NSNumberFormatterDecimalStyle];

NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"fr_FR"];

[formatter setLocale:locale];

NSLog(@"%@", [formatter stringFromNumber:number]);

或者,简要地

NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:@"100.1"];
NSLog(@"%@", [NSNumberFormatter localizedStringFromNumber:number numberStyle:NSNumberFormatterDecimalStyle]);

如果您只想使用当前的语言环境。

总之:

  1. NSDecimalNumber 只是存储。记录它不会反映任何关于语言环境的信息。
  2. 为了让 NSDecimalNumber 正确存储一个数字,它的语言环境需要与预期输入的语言环境相匹配(-[NSLocale currentLocale]这里是一个不错的选择)。
  3. 为了显示给定区域设置正确格式的数字,请使用 NSNumberFormatter。

编辑:

好的,我对此进行了更多研究。

在 GNUStep 中,它看起来最终使用了NSDecimalSeparatorin的值NSUserDefaults(通过快速浏览他们的代码)。

做一些实验,我发现以下都不会影响默认的解析行为,据我所知:

  1. NSDecimalSeparatorNSUserDefaults.
  2. AppleLocaleNSUserDefaults.
  3. NSLocaleCodeNSUserDefaults.
  4. 为 设置的值CFBundleDevelopmentRegion
  5. 环境的LANG/ LC_ALL/etc... 值。
  6. +[NSLocale systemLocale].

显然不是+[NSLocale currentLocale],因为这个问题源于当前语言环境无效的事实。

于 2013-03-20T21:47:04.350 回答