簡體   English   中英

如何將浮點數轉換為由字節分子和分母表示的最接近的分數?

[英]How can I turn a floating point number into the closest fraction represented by a byte numerator and denominator?

如何編寫一個給定浮點數的算法,並嘗試使用分子和分母盡可能准確地表示,兩者都限制在 Java 字節的范圍內?

這樣做的原因是 I2C 設備需要一個分子和分母,而給它一個浮點數是有意義的。

例如, 3.1415926535...將導致245/78 ,而不是314/10022/7

就效率而言,這將在程序開始時調用大約 3 次,但在那之后根本不會調用。 因此,慢速算法還不錯

這是我最后使用的代碼(基於 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};
}

感謝那些幫助過的人

你對效率有多擔心? 如果您沒有每秒調用此轉換函數 100 次或更多次,那么通過每個可能的分母(很可能只有 255 個)並找出最接近的分母可能並不難近似(計算分子與分母是常數時間)。

我已經編寫了一些代碼(甚至在 Java 中)來完成您所要求的事情。 就我而言,我需要將比例因子顯示為百分比和比率。 最熟悉的示例是您在圖像編輯器(例如 GIMP)中看到的縮放對話框。

你可以在這里找到我的代碼,在從第 1161 行開始的 updateRatio() 方法中。你可以簡單地使用它,只要 LGPL 許可證適合你。 我所做的基本上遵循了 GIMP 中所做的事情——這是其中幾乎只有一種有效、明智的方法來做的事情之一。

我會發表評論,但我還沒有代表...

埃里克的上述回答沒有考慮可能獲得確切結果的情況。 例如,如果您使用 0.4 作為輸入,那么表示應該是 2/5,在這種情況下,您最終會在循環的第三次迭代中除以零(第二次循環中的 r=0 => r = 1/第三個錯誤)。

因此,您要修改 while 循環以排除該選項:

while(true)

應該

while(r != 0)

使用 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);
}

你應該看看法雷數列。
給定分母 d 的限制,法雷數列是分母 <= d 的每個分數。

然后,您只需將浮點數與 Farey 分數的解析值進行比較。 這將允許您用重復的十進制實數來表示您的浮點數。

這是有關其在java中實現的頁面:
http://www.merriampark.com/fractions.htm

這是他們使用的一個很好的演示:
http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fractions/fareySB.html

出於好奇,我來到這里,但我記得 Python 標准庫分數中有這樣的功能。

也許,我們可以看看這兩個函數的源代碼:

如何在雙數據類型中存儲 18 位數字(當分子<denominator)< div><div id="text_translate"><p> 我想做的是,例如</p><pre>int num = 18, den = 19; double q=(double)num/(double)den;</pre><p> 返回 0.9473684210526315</p><p> 但我想要的是 0.947368421052631578</p><p> 因為 num<den,小數點左邊總是“0”,我是否可以使用這些字符的空間並將其改為“78”? 如果我不能那樣做,另一種方法是什么?</p><p> 我需要這個的原因是一個 LC 問題。 </p></div></denominator)<>

[英]how to store 18 digits in a double datatype (when numerator<denominator)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM