4

浮動小数点数を指定し、Java バイトの範囲に制限された分子と分母を使用してできるだけ正確に表現しようとするアルゴリズムを作成するにはどうすればよいですか?

この理由は、I2C デバイスが分子と分母を必要としているのに対し、float を与えることは理にかなっているからです。

たとえば、またはではなく、 になり3.1415926535...ます。245/78314/10022/7

効率的には、プログラムの開始時に 3 回程度呼び出されますが、その後はまったく呼び出されません。したがって、遅いアルゴリズムはそれほど悪くありません。

4

6 に答える 6

5

これが私が最後に使用したコードです(uckelmanのコードに基づく)

public static int[] GetFraction(double input)
{
    int p0 = 1;
    int q0 = 0;
    int p1 = (int) Math.floor(input);
    int q1 = 1;
    int p2;
    int q2;

    double r = input - p1;
    double next_cf;
    while(true)
    {
        r = 1.0 / r;
        next_cf = Math.floor(r);
        p2 = (int) (next_cf * p1 + p0);
        q2 = (int) (next_cf * q1 + q0);

        // Limit the numerator and denominator to be 256 or less
        if(p2 > 256 || q2 > 256)
            break;

        // remember the last two fractions
        p0 = p1;
        p1 = p2;
        q0 = q1;
        q1 = q2;

        r -= next_cf;
    }

    input = (double) p1 / q1;
    // hard upper and lower bounds for ratio
    if(input > 256.0)
    {
        p1 = 256;
        q1 = 1;
    }
    else if(input < 1.0 / 256.0)
    {
        p1 = 1;
        q1 = 256;
    }
    return new int[] {p1, q1};
}

助けてくれた人たちに感謝します

于 2009-11-01T17:08:32.567 に答える
3

あなたが求めていることだけを行うためのコードを (Java でも) 書きました。私の場合、倍率をパーセンテージと比率の両方で表示する必要がありました。これの最もよく知られている例は、GIMP などの画像エディターで表示されるズーム ダイアログです。

私のコードは、こちらの 1161 行目から始まる updateRatio() メソッドにあります。LGPL ライセンスが有効である限り、そのまま使用できます。私が行ったことは、基本的に GIMP で行われたことに従っています。これは、効率的で賢明な方法がほぼ 1 つしかないものの 1 つです。

于 2009-11-01T13:22:54.130 に答える
3

効率性についてどの程度心配していますか? この変換関数を 1 秒間に 100 回以上呼び出していない場合、考えられるすべての分母 (ほとんどの場合 255 個のみ) を力ずくで調べて、どれが最も近いかを見つけるのはおそらくそれほど難しくありません。近似 (分母に合わせて分子を計算するのは一定時間です)。

于 2009-11-01T11:39:17.210 に答える
2

コメントしたいのですが、まだ担当者がいません...

上記のエリックの答えは、正確な結果が可能な場合を考慮していません。たとえば、入力として 0.4 を使用する場合、表現は 2/5 である必要があります。この場合、ループの 3 回目の反復でゼロによる除算になります (2 番目のループで r=0 => r = 1/ 3 番目の r エラー)。

そのため、while ループを変更してそのオプションを除外します。

while(true)

する必要があります

while(r != 0)
于 2009-12-16T23:25:17.133 に答える
1

Apache の BigFraction の使用について:

import org.apache.commons.math3.fraction.BigFraction;

public static BigFraction GetBigFraction(double input)
{
    int precision = 1000000000;
    return new BigFraction((int)(input * (double)precision), precision);
}
于 2013-01-04T14:12:35.957 に答える
1

ファリー数列を見るべきです。
分母 d に極限があると、分母 <= d を持つすべての分数がファレー数列になります。

次に、フロートを取り、それをファレイ分数の解決された値と比較するだけです。これにより、繰り返し小数の実数でフロートを表すことができます。

これは Java での実装に関するページです:
http://www.merriampark.com/fractions.htm

ここにそれらの使用の良いデモンストレーションがあります:
http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fractions/fareySB.html

于 2011-11-08T00:05:05.720 に答える