NSNumberFormatter将大(但可表示)整数解析为双精度



我一直在使用以下方法将NSString解析为NSNumber:

// (a category method on NSString)
-(NSNumber*) tryParseAsNumber {
  NSNumberFormatter* formatter = [NSNumberFormatter new];
  [formatter setNumberStyle:NSNumberFormatterDecimalStyle];
  return [formatter numberFromString:self];
}

我进行了测试,验证这是正确的工作:

test(@"".tryParseAsNumber == nil);
...
test([(@NSUIntegerMax).description.tryParseAsNumber isEqual:@NSUIntegerMax]);
...

当我切换到在iPhone 6上进行测试时,最大值测试开始失败,可能是因为NSUInteger现在是64位而不是32位。格式化程序返回的值现在是双1.844674407370955e+19,而不是uint64_t 18446744073709551615

有没有一个内置方法可以完全成功地处理所有的int64和无符号int64,或者我必须自己实现一个?

+ [NSNumber numberWithLongLong:]
+ [NSNumber numberWithUnsignedLongLong:]

你试过这些吗?

编辑

我完全不确定你最终会对NSNumber的实例做什么,但考虑到NSDecimalNumber似乎正是你想要做的:

NSDecimalNumber *decNum = [NSDecimalNumber decimalNumberWithString:@"18446744073709551615"];
NSLog(@"%@", decNum);

产生:

2014-09-21 15:11:25.472 Test[1138:812724] 18446744073709551615

还有一点需要考虑:NSDecimalNumber"是"NSNumber,因为它是后者的子类。因此,无论你能用NSNumber做什么,你都可以用NSDecimalNumber做。

trudyscont的回答让我明白了。

NSDecimalNumber decimalNumberWithString:能够完全精确地进行解析,但它允许一些错误的输入(例如,"88ffhih"被解析为88)。另一方面,NSNumberFormatter numberFromString:总是检测到错误的输入,但会失去精度。他们有相反的弱点。

所以。。。两者兼而有之。例如,这里有一个方法应该解析可表示的NSUIntegers,但不解析其他内容:

+(NSNumber*) parseAsNSUIntegerElseNil:(NSString*)decimalText {
    // NSNumberFormatter.numberFromString is good at noticing bad inputs, but loses precision for large values
    // NSDecimalNumber.decimalNumberWithString has perfect precision, but lets bad inputs through sometimes (e.g. "88ffhih" -> 88)
    // We use both to get both accuracy and detection of bad inputs
    NSNumberFormatter* formatter = [NSNumberFormatter new];
    [formatter setNumberStyle:NSNumberFormatterDecimalStyle];
    if ([formatter numberFromString:decimalText] == nil) {
        return nil;
    }
    NSNumber* value = [NSDecimalNumber decimalNumberWithString:decimalText];
    // Discard values not representable by NSUInteger
    if (![value isEqual:@(value.unsignedIntegerValue)]) {
        return nil;
    }
    return value;
}

相关内容

  • 没有找到相关文章

最新更新