如何编写一个给定浮点数的算法,并尝试使用分子和分母尽可能精确地表示,两者都限制在java字节的范围内?原因是i2c设备需要一个分子和分母,而给它一个浮点数是有意义的。例如, 3.1415926535... 会导致 245/78 ,而不是 314/100 或者 22/7 .就效率而言,这个函数在程序开始时会被调用三次,但在那之后就不会了。所以一个缓慢的算法也不算太糟。
3.1415926535...
245/78
314/100
22/7
kyxcudwk1#
使用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); }
bjg7j2ky2#
你有多担心效率?如果你不是每秒调用这个转换函数100次或更多次,那么用暴力穿透每一个可能的分母(很可能只有255个分母)并找出哪一个给出了最接近的近似值(计算分母所对应的分子是常数时间)可能就不那么困难了。
0vvn1miw3#
我已经写了一些代码(甚至用java)来做你想要的事情。在我的例子中,我需要以百分比和比率的形式显示比例因子。最常见的例子是在图像编辑器(如gimp)中看到的缩放对话框。您可以从第1161行开始的updateratio()方法中找到我的代码。只要lgpl许可证适合您,您就可以简单地使用它。我所做的基本上是遵循在gimp中所做的事情——这是其中的一件事,其中几乎只有一种有效的、明智的方法来做。
uqcuzwp84#
我想评论一下,但我还没有。。。上面埃里克的回答没有考虑到可能得到确切结果的情况。例如,如果您使用0.4作为输入,那么表示应该是2/5,在这种情况下,在循环的第三次迭代中,您将得到被零除的结果(第二次循环中的r=0=>第三次循环中的r=1/r错误)。因此要修改while循环以排除该选项:
while(true)
应该是
while(r != 0)
5rgfhyps5#
下面是我最后使用的代码(基于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}; }
谢谢你的帮助
uxh89sit6#
你应该看看法雷的顺序。给定分母d的极限,farey序列是分母<=d的每个分数。然后,您只需将浮点数与farey分数的解析值进行比较。这将允许您用重复的十进制实数来表示浮点值。以下是关于其java实现的页面:http://www.merriampark.com/fractions.htm下面是一个很好的演示:http://www.maths.surrey.ac.uk/hosted-sites/r.knott/fractions/fareysb.html
6条答案
按热度按时间kyxcudwk1#
使用apache的bigfraction怎么样:
bjg7j2ky2#
你有多担心效率?如果你不是每秒调用这个转换函数100次或更多次,那么用暴力穿透每一个可能的分母(很可能只有255个分母)并找出哪一个给出了最接近的近似值(计算分母所对应的分子是常数时间)可能就不那么困难了。
0vvn1miw3#
我已经写了一些代码(甚至用java)来做你想要的事情。在我的例子中,我需要以百分比和比率的形式显示比例因子。最常见的例子是在图像编辑器(如gimp)中看到的缩放对话框。
您可以从第1161行开始的updateratio()方法中找到我的代码。只要lgpl许可证适合您,您就可以简单地使用它。我所做的基本上是遵循在gimp中所做的事情——这是其中的一件事,其中几乎只有一种有效的、明智的方法来做。
uqcuzwp84#
我想评论一下,但我还没有。。。
上面埃里克的回答没有考虑到可能得到确切结果的情况。例如,如果您使用0.4作为输入,那么表示应该是2/5,在这种情况下,在循环的第三次迭代中,您将得到被零除的结果(第二次循环中的r=0=>第三次循环中的r=1/r错误)。
因此要修改while循环以排除该选项:
应该是
5rgfhyps5#
下面是我最后使用的代码(基于uckelman的代码)
谢谢你的帮助
uxh89sit6#
你应该看看法雷的顺序。
给定分母d的极限,farey序列是分母<=d的每个分数。
然后,您只需将浮点数与farey分数的解析值进行比较。这将允许您用重复的十进制实数来表示浮点值。
以下是关于其java实现的页面:
http://www.merriampark.com/fractions.htm
下面是一个很好的演示:
http://www.maths.surrey.ac.uk/hosted-sites/r.knott/fractions/fareysb.html