4

2 つの NSDecimalNumbers があり、一方を他方のべき乗に適用する必要があります。元々、このコードは double を使用していたので、次のように 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
4

2 に答える 2

4

Joe が指摘しているように、正の整数乗数に対してこれを行いたい場合はNSDecimalPower()、NSDecimalNumber から派生した NSDecimal 構造体で使用できます (パフォーマンス上の理由から、構造体を使用することを個人的に好みます)。

負の整数と小数値を扱うより一般的なケースについては、Dave DeLong の DDMAthParser ライブラリから変更したコードをいくつか用意しています。その後、彼はこのライブラリの NSDecimal 部分を削除しましたが、このサポートの最後のコミットを見つけることができます。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;
}

これにより、正の整数乗、負の整数乗、根に直接対応する分数乗の正確な計算が実行されます。ただし、これらのビンの 1 つにきれいに分類されない分数べき乗の浮動小数点計算にフォールバックします。

残念ながら、これには彼の他のサポート機能のいくつかが機能する必要があります。したがって、この機能を提供する彼の_DDDecimalFunctions.hおよび_DDDecimalFunctions.mの拡張バージョンをアップロードしました。また、NSDecimal 三角法、対数、およびその他のいくつかの関数も含まれています。現在、接線実装での収束に問題がいくつかあります。そのため、これに関する公開投稿を終了していません。

于 2012-08-23T15:21:27.953 に答える