如何将NSDecimalNumber转换为double

时间:2012-07-18 19:10:46

标签: objective-c ios double nsdecimalnumber

我有一个值存储为NSDecimalNumber,当我将其转换为double时,它会失去精度。

对于我正在调试的当前数据,值为0.2676655。当我发送一个doubleValue消息时,我得到0.267665。它正在截断而不是舍入,这会破坏一些使用哈希来检测同步操作的数据更改的代码。

NSDecimalNumber实例来自第三方框架,所以我不能用原始double替换它。最终它被插入一个NSMutableString所以我在一个字符串表示后,但它需要通过格式说明符“%。6lf”传递,基本上我需要十进制后的六位数,所以它看起来像0.267666。

如何在不失去精确度的情况下实现这一目标?如果有一种很好的方法来格式化NSDecimalNumber而不转换为可以正常工作的双精度。

2 个答案:

答案 0 :(得分:4)

  

NSDecimalNumber实例来自第三方框架,所以我   不能用原始的双倍替换它。

是的,你可以。 NSDecimalNumber是NSNumber的不可变子类,在转换时有点太有用了:

double myDub = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithDouble:((double)0.2676655)] doubleValue]];
  

最终它被插入一个NSMutableString,所以我在一个之后   字符串表示,但它需要通过格式传递   "%。6lf"的说明符,基本上我需要十进制后的六位数   它看起来像0.267666。

不幸的是,双精度不会变圆,但是得到一个字符串的值减去百万分之一并不是一件大事(我希望):

NSDecimalNumber *num = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithDouble:((double)0.2676655)] decimalValue]];
NSString *numString = [NSString stringWithFormat:@"%.6lf", [num doubleValue]];
NSLog(@"%@",numString);

答案 1 :(得分:2)

我认为你走错了路,而且在某个地方迷失了。

首先,请记住,在Objective-c lond double中不支持,因此您最好使用%f而不是%lf。 [可在目标c运行时编程指南的“类型编码”下的文档库中找到]

然后我宁愿期望值显示为被截断,因为doubleValue返回一个近似值,但您使用的范围仍然在正确的范围内。

您应该使用简单的格式化程序而不是移动数字,例如:

    // first line as an example for your real value
    NSDecimalNumber *value = [NSDecimalNumber decimalNumberWithString:@"0.2676655"];
    NSNumberFormatter *numFmt = [[NSNumberFormatter alloc] init];
    [numFmt setMaximumFractionDigits:6];
    [numFmt setMinimumFractionDigits:6];
    [numFmt setMinimumIntegerDigits:1];
    NSLog(@"Formatted number %@",[numFmt stringFromNumber:value]);

如果需要,这具有使用区域设置感知格式化程序的另一个好处。数字格式化程序的结果是所需的字符串。