home4/src/Lfraction.java

237 lines
5.9 KiB
Java

import java.util.*;
/** This class represents fractions of form n/d where n and d are long integer
* numbers. Basic operations and arithmetics for fractions are provided.
*/
public class Lfraction implements Comparable<Lfraction> {
/** Main method. Different tests. */
public static void main (String[] param) {
// TODO!!! Your debugging tests here
}
private long nu;
private long de;
/** Constructor.
* @param a numerator
* @param b denominator > 0
*/
public Lfraction (long a, long b) {
if (b < 1) {
throw new RuntimeException("Denominator can't be 0 or less");
}
this.nu = a;
this.de = b;
}
/** Public method to access the numerator field.
* @return numerator
*/
public long getNumerator() {
return this.nu;
}
/** Public method to access the denominator field.
* @return denominator
*/
public long getDenominator() {
return this.de;
}
/** Conversion to string.
* @return string representation of the fraction
*/
@Override
public String toString() {
return ""+Long.toString(this.nu)+"/"+Long.toString(this.de);
}
/** Equality test.
* @param m second fraction
* @return true if fractions this and m are equal
*/
@Override
public boolean equals (Object m) {
Lfraction other = (Lfraction) m;
if (other.de == this.de) {
return this.nu == other.nu;
} else {
double dif;
if (other.de > this.de) {
dif = other.de / this.de;
} else {
dif = this.de / other.de;
}
return (this.nu*dif) == other.nu;
}
}
/** Hashcode has to be equal for equal fractions.
* @return hashcode
*/
@Override
public int hashCode() {
return Objects.hash(this.nu, this.de);
}
/** Reduce the fraction
* @return reduced Lfraction
*/
public Lfraction reduce() {
long common;
if (this.nu == this.de) {
common = this.nu;
} else {
long de1;
long de2;
if (this.nu > this.de) {
de1 = this.nu;
de2 = this.de;
} else {
de1 = this.de;
de2 = this.nu;
}
long f;
while (de2 != 0) {
f = de2;
de2 = de1 % de2;
de1 = f;
}
common = de1;
}
return new Lfraction(this.nu / common, this.de / common);
}
/** Sum of fractions.
* @param m second addend
* @return this+m
*/
public Lfraction plus (Lfraction m) {
if (this.de == m.de) {
return new Lfraction(this.nu + m.nu, this.de);
} else {
return new Lfraction((m.nu*this.de)+(this.nu*m.de), (m.de*this.de));
}
}
/** Multiplication of fractions.
* @param m second factor
* @return this*m
*/
public Lfraction times (Lfraction m) {
return new Lfraction(this.nu * m.nu, this.de * m.de).reduce();
}
/** Inverse of the fraction. n/d becomes d/n.
* @return inverse of this fraction: 1/this
*/
public Lfraction inverse() {
if (this.nu < 1) {
return new Lfraction(-this.de, -this.nu);
} else {
return new Lfraction(this.de, this.nu);
}
}
/** Opposite of the fraction. n/d becomes -n/d.
* @return opposite of this fraction: -this
*/
public Lfraction opposite() {
return new Lfraction(-this.nu, this.de);
}
/** Difference of fractions.
* @param m subtrahend
* @return this-m
*/
public Lfraction minus (Lfraction m) {
if (this.de == m.de) {
return new Lfraction(this.nu - m.nu, this.de);
} else {
return new Lfraction((this.nu*m.de)-(m.nu*this.de), (m.de*this.de)).reduce();
}
}
/** Quotient of fractions.
* @param m divisor
* @return this/m
*/
public Lfraction divideBy (Lfraction m) {
long nu = Math.abs(this.nu * m.de);
long de = Math.abs(this.de * m.nu);
return new Lfraction(nu, de).reduce();
}
/** Comparision of fractions.
* @param m second fraction
* @return -1 if this < m; 0 if this==m; 1 if this > m
*/
@Override
public int compareTo (Lfraction m) {
if (this.equals(m)) {
return 0;
} else if (this.nu * m.de < m.nu * this.de) {
return -1;
} else {
return 1;
}
}
/** Clone of the fraction.
* @return new fraction equal to this
*/
@Override
public Object clone() throws CloneNotSupportedException {
return new Lfraction(this.nu, this.de);
}
/** Integer part of the (improper) fraction.
* @return integer part of this fraction
*/
public long integerPart() {
return this.nu/this.de;
}
/** Extract fraction part of the (improper) fraction
* (a proper fraction without the integer part).
* @return fraction part of this fraction
*/
public Lfraction fractionPart() {
if (this.nu >= this.de || -this.nu >= this.de) {
return new Lfraction(this.nu % this.de, this.de);
} else {
return new Lfraction(this.nu, this.de);
}
}
/** Approximate value of the fraction.
* @return numeric value of this fraction
*/
public double toDouble() {
return (double)this.nu/this.de;
}
/** Double value f presented as a fraction with denominator d > 0.
* @param f real number
* @param d positive denominator for the result
* @return f as an approximate fraction of form n/d
*/
public static Lfraction toLfraction (double f, long d) {
return new Lfraction(Math.round(f * d), d);
}
/** Conversion from string to the fraction. Accepts strings of form
* that is defined by the toString method.
* @param s string form (as produced by toString) of the fraction
* @return fraction represented by s
*/
public static Lfraction valueOf (String s) {
String[] parts = s.split("/");
return new Lfraction(Long.parseLong(parts[0]), Long.parseLong(parts[1]));
}
}