NSDecimalNumber 的 NSDecimalNumber 次方

2024-01-11

我有两个 NSDecimalNumbers,我需要应用一个到另一个的幂,最初这段代码使用的是双精度数,我可以使用 pow() 函数来计算它,如下所示:

double result = pow(value1, value2);

我遇到的问题是我正在将代码转换为使用 NSDecimalNumbers,尽管它们包含方法 toThePowerOf,但它只接受 int 值。目前,我对这个问题的唯一解决方案是暂时转换 NSDecimalNumbers,但这会导致精度损失。

double value1 = [decimal1 doubleValue];
double value2 = [decimal2 doubleValue];

double result = pow(value1, value2);
NSDecimalNumber *decimalResult = [[NSDecimalNumber alloc] initWithDouble:result];

有没有办法可以使用 NSDecimalNumbers 进行此计算而不丢失精度?

我需要它来处理非整数值,例如:

value1 = 1.06
value2 = 0.0277777777

正如 Joe 指出的,如果你想对正整数幂执行此操作,你可以使用NSDecimalPower()在从 NSDecimalNumber 派生的 NSDecimal 结构上(我个人更喜欢使用这些结构,因为性能原因 https://stackoverflow.com/questions/1704504/what-is-the-right-choice-between-nsdecimal-nsdecimalnumber-cfnumber/1710277#1710277).

对于使用负整数和小数值的更一般情况,我从 Dave DeLong 的 DDMathParser 库修改了一些代码。此后他删除了该库的 NSDecimal 部分,但您可以找到此支持的最后一次提交 https://github.com/davedelong/DDMathParser/commit/6121b9d8c3651bcafeb8d89063471b1ba2aa9d3c。我将 Dave 的指数支持扩展为以下函数:

extern NSDecimal DDDecimalPower(NSDecimal d, NSDecimal power) {
    NSDecimal r = DDDecimalOne();
    NSDecimal zero = DDDecimalZero();
    NSComparisonResult compareToZero = NSDecimalCompare(&zero, &power);
    if (compareToZero == NSOrderedSame) {
        return r;
    }
    if (DDDecimalIsInteger(power))
    {
        if (compareToZero == NSOrderedAscending)
        {
            // we can only use the NSDecimal function for positive integers
            NSUInteger p = DDUIntegerFromDecimal(power);
            NSDecimalPower(&r, &d, p, NSRoundBankers);
        }
        else
        {
            // For negative integers, we can take the inverse of the positive root
            NSUInteger p = DDUIntegerFromDecimal(power);
            p = -p;
            NSDecimalPower(&r, &d, p, NSRoundBankers);
            r = DDDecimalInverse(r);
        }
    } else {
        // Check whether this is the inverse of an integer        
        NSDecimal inversePower = DDDecimalInverse(power);
        NSDecimalRound(&inversePower, &inversePower, 34, NSRoundBankers); // Round to 34 digits to deal with cases like 1/3

        if (DDDecimalIsInteger(inversePower))
        {
            r = DDDecimalNthRoot(d, inversePower);
        }
        else
        {
            double base = DDDoubleFromDecimal(d);
            double p = DDDoubleFromDecimal(power);
            double result = pow(base, p);
            r = DDDecimalFromDouble(result);
        }        
    }
    return r;
}

这对直接映射到根的正整数幂、负整数幂和分数幂进行精确计算。不过,它仍然依赖于分数幂的浮点计算,而这些分数幂并没有完全落入这些容器之一。

不幸的是,这需要他的一些其他支持功能才能工作。因此,我上传了他的增强版本_DDDecimalFunctions.h http://sunsetlakesoftware.com/sites/default/files/_DDDecimalFunctions.h and _DDDecimalFunctions.m http://sunsetlakesoftware.com/sites/default/files/_DDDecimalFunctions.m提供此功能的。它们还包括 NSDecimal 三角函数、对数和一些其他函数。目前,切线实现的收敛存在一些问题,这就是为什么我还没有完成有关此问题的公开帖子。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NSDecimalNumber 的 NSDecimalNumber 次方 的相关文章

随机推荐