繁体   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