本着使用现有的,经过测试的和稳定的代码库的精神,我开始使用Apache-Commons-Math library及其BigFraction
class为我正在编写的称为RationalCalc的Android应用执行一些合理的计算。
除了一个令人烦恼的问题,它对我执行的所有任务都非常有用。当除某些BigFraction
值时,得到的结果不正确。
如果我用除数的倒数创建一个BigFraction
并乘以乘法,则会得到相同的错误答案,但也许这是库在内部所做的。
有人知道我在做什么错吗?
除法在BigFraction
为2.5而不是2.51、2.49等的情况下可以正常工作...
[更新]
这确实是apache-commons-math 2.0库中的错误。该错误已在2.1版中修复。
现在,它已在错误跟踪器的“已修复问题”部分中列出:
When multiplying two BigFraction objects with numerators larger than will fit in an java-primitive int the result of BigFraction.ZERO is incorrectly returned.。
感谢@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
最佳答案
在构造函数中提供double
会导致舍入错误。使用精确的分子和分母将得到预期的结果:
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