1

既存のテスト済みの安定したコードライブラリを使用するという精神で、Apache-Commons-MathライブラリとそのBigFractionクラスを使用して、RationalCalcと呼ばれるAndroidアプリの合理的な計算を実行し始めました。

それは、1つの厄介な問題を除いて、私がそれに投げかけたすべてのタスクに最適です。特定のBigFraction値を除算すると、間違った結果が得られます。

除数の逆数を使用してを作成し、BigFraction代わりに乗算すると、同じ間違った答えが得られますが、おそらくそれがライブラリが内部で行っていることです。

誰かが私が間違っていることを知っていますか?

除算BigFractionは2.5のaで正しく機能しますが、2.51、2.49などでは機能しません。

[アップデート]

これは確かにapache-commons-math2.0ライブラリのバグでした。バグはv.2.1で修正されています。

これで、バグトラッカーの[修正された問題]セクションに一覧表示されます。

2つのBigFractionオブジェクトに、java-primitive intに収まるよりも大きい分子を掛けると、BigFraction.ZEROの結果が誤って返されます。

問題の再現を試み、正しい軌道に乗せてくれた@BartKに感謝します。

[/アップデート]

// *** incorrect! ***
BigFraction one = new BigFraction(1.524);
//one: 1715871458028159 / 1125899906842624

BigFraction two = new BigFraction(2.51);
//two: 1413004383087493 / 562949953421312

BigFraction three = one.divide(two);
//three: 0

Log.i("solve", three.toString());
//should be 0.607171315  ??
//returns 0


// *** correct! ****
BigFraction four = new BigFraction(1.524);
//four: 1715871458028159 / 1125899906842624

BigFraction five = new BigFraction(2.5);
//five: 5 / 2

BigFraction six = four.divide(five);
//six: 1715871458028159 / 2814749767106560

Log.i("solve", six.toString());
//should be 0.6096  ??
//returns 0.6096
4

1 に答える 1

3

コンストラクdoubleターに 's を指定すると、丸め誤差が発生します。正確な分子と分母を使用すると、期待される結果が得られます。

public class CommonsMathTest {

    public static void main(String[] args) {

        BigFraction one = new BigFraction(1524, 1000);
        System.out.println("one   = " + one);

        BigFraction two = new BigFraction(251, 100);
        System.out.println("two   = " + two);

        BigFraction three = one.divide(two);
        System.out.println("three = " + three);

        BigFraction four = new BigFraction(1524, 1000);
        System.out.println("four  = " + four);

        BigFraction five = new BigFraction(5, 2);
        System.out.println("five  = " + five);

        BigFraction six = four.divide(five);
        System.out.println("six   = " + six + " = " + six.bigDecimalValue());
    }
}

生成:

one   = 381 / 250
two   = 251 / 100
three = 762 / 1255
four  = 381 / 250
five  = 5 / 2
six   = 381 / 625 = 0.6096

編集

ところで、あなたの出力を再現できませんでした。Commons-Math 2.1 を使用すると、次のようになります。

BigFraction one = new BigFraction(1.524);
BigFraction two = new BigFraction(2.51);
BigFraction three = one.divide(two);
System.out.println(three.toString() + " = " +three.doubleValue());

あなたが言ったように生成しません0が、印刷します:

1715871458028159 / 2826008766174986 = 0.6071713147410359
于 2010-05-14T06:50:02.457 に答える