在Objective-C中获得NSDecimalNumber的指数?

时间:2012-09-28 15:52:03

标签: objective-c ios

给定NSDecimalNumber,我如何找到指数(比例)?

虽然原则上可以通过首先转换为NSString然后进行一些丑陋的字符串操作来实现这一点,但我宁愿避免它。

使用Java BigDecimal,我可以调用scale()方法来获得比例。

NSDecimalNumber是否存在类似的简洁方法?

5 个答案:

答案 0 :(得分:3)

如果由于某种原因确实需要指数(除了简单显示,你可以配置一个数字格式器给你),你可以用-doubleValue方法得到原始的double,然后使用{{1获取尾数和指数值。

用于执行和存储浮点数学的对象背后的整个设计是您可以更有效地处理计算和精度错误,但是,一旦您从标量(例如frexp(3)转换,该设计的限制或者尾数和指数的组合),你应该保持在对象框架内,而不是转换回(可能)不太精确的格式。

我建议使用double是最好的选择,因为其他答案建议访问可能发生变化的私人结构记录,并且使用这些记录表明没有精确度损失,事实上,实际情况可能很好(如记录的那样)在头文件中)。转换为double时,您和使用/读取代码的人确切知道可能出现的精度错误,因为该类型已被很好地理解并且有很好的文档记录。

最后,如果您想确定转换是否会导致错误,您可以创建并使用NSDecimalNumberHandler,它将为您提供有关转换时可能出现的舍入/精度错误类型的信息到双标量类型。

我还建议您使用apple bug报告者添加一个增强请求,声明您希望直接访问指数,并可能添加更高精度类型,如-doubleValue方法。

编辑包含更多信息

答案 1 :(得分:2)

您可以在NSDecimal上访问它:

int exponent = decimalNumber.decimalValue._exponent;

答案 2 :(得分:1)

不,它看起来不像NSDecimalNumber。我想你可能要写自己的。

但是,如果您不介意挖掘一下(并忽略文档警告),您可能会看到从NSDecimal structure返回的-decimalValue - 它有许多字段可供您使用可能会到达。这是否主观上比你的NSString操作更好或更差取决于你。

答案 3 :(得分:0)

如果你想让表达式在base-10表单上(frexp(3)似乎只做base-2),你可以试试这个:

double mantissa = [someDecimalNumber doubleValue];
int exp = 0;

if (mantissa >= 1.0f) {
    while (mantissa >= 1.0f) {
        mantissa = mantissa / 10.0f;
        exp++;
    }
} else {
    while (mantissa*10.0f < 1.0f) {
        mantissa = mantissa * 10.0f;
        exp--;
    }
}

NSLog(@"%f = %f x 10^%d", [someDecimalNumber doubleValue], mantissa, exp);

答案 4 :(得分:-1)

您可以将数字与使用等于1的尾数创建的NSDecimalNumber实例进行比较,从而更改指数。它可以像二进制搜索一样工作。