Java library for Rational and Complex number calculations without loosing precision.
After building using Your favourite building tool, just add BigNumbers as dependency.
<dependency>
<groupId>net.turtle.math</groupId>
<artifactId>bignumbers</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
compile group: 'net.turtle.math', name: 'bignumbers', version: '0.0.1-SNAPSHOT'
compile('net.turtle.math:bignumbers:0.0.1-SNAPSHOT')
BigNumbers contains mainly 2 classes BigRational
and BigComplex
which wrap mathematical Rational and Complex numbers. Based on them, other structures were created like BigVector and BigMatrix.
Instances of every core classes are immutable in the same way like other similar classes from java.math.*
package. It means that if we want to calculate 2+3 expecting the result 5, such code does not show the correct result:
final BigRational rational = new BigRational("3");
rational.add(new BigRational("2"));
System.out.println(rational.toString()); // Prints 3 instead of 5
It is so because add
method creates new instance of result object and rational
instance stays untouch. The correct usage is like this:
final BigRational rational = new BigRational("3");
final BigRational sum = rational.add(new BigRational("2"));
System.out.println(sum.toString()); // Prints 5 as expected
We assign the result of add
method to another variable which contains the expected result.
Following Wikipedia:
Rational number is any number that can be expressed as the quotient or fraction p/q of two integers, p and q, with the denominator q not equal to zero.
BigRational
class wrapps Rational number and uses numerator and denominator to express it.
BigRational
can be constructed just like regular BigDecimal
class:
final BigRational br1 = new BigRational("2"); // numerator 2, denominator 1
final BigRational br1 = new BigRational("2.34"); // numerator 234, denominator 100
final BigRational br1 = new BigRational("2/3"); // numerator = 2, denominator = 3
final BigRational br1 = new BigRational(BigInteger.valueOf("1"), BigInteger.valueOf("3")); // num = 1, den = 3
Unlike BigDecimal
, working with BigRational
does not loose precision as much as it is possible. E.g.
final BigRational oneThird = new BigRational("1/3"); // It is not 0.33333...
final BigRational twoThird = new BigRational("2/3"); // It is not 0.66666...
final BigRational one = oneThird.add(twoThird);
System.out.println(one.toString()); // Prints 3/3 instread of something like 0.999999...
Same rule works for every other simple operation. As You can see, the result fraction is not cancelled by default due to performance impact which may be not needed for some users. Also the fraction is not normalized in the way that only numerator is the "owner" of the sign (positive/negative) and denominator is always positive. During operations, denominator can be negative e.g.:
final BigRational oneThird = new BigRational("1/3"); // Normalized
final BigRational minusTwoThird = new BigRational("-2/3"); // Normalized
final BigRational result = oneThird.divide(minusTwoThird);
System.out.println(result.toString()); // Prints 3/-6 which is correct but not normalized
To normalize the fraction - which means both: normalizing sign and canceling the fraction, You can use at any time:
System.out.println(result.normalizeSignum().toString()); // Prints -3/6
System.out.println(result.cancel().toString()); // Prints 1/-2
System.out.println(result.normalize().toString()); // Does both and prints -1/2
Following Wikipedia:
A complex number is an element of a number system that contains the real numbers and a specific element denoted i, called the imaginary unit, and satisfying the equation i2 = −1.
BigComplex
can be constructed like BigRational
. Additionally it can contain an imaginary part:
final BigComplex bc1 = new BigComplex("2.34+2i"); // real part: 234/100, imaginary part: 2
final BigComplex bc1 = new BigComplex(new BigRational("2"), new BigRational("3")); // real part = 2, imaginary part = 3