package org.jcodec.common.model;
import static org.jcodec.common.StringUtils.splitS;
import static org.jcodec.common.model.RationalLarge.reduceLong;
import org.jcodec.common.tools.MathUtil;
/**
* This class is part of JCodec ( www.jcodec.org ) This software is distributed
* under FreeBSD License
*
* @author The JCodec project
*
*/
public class Rational {
public static final Rational ONE = new Rational(1, 1);
public static final Rational HALF = new Rational(1, 2);
public static final Rational ZERO = new Rational(0, 1);
final int num;
final int den;
public static Rational R(int num, int den) {
return new Rational(num, den);
}
public static Rational R1(int num) {
return R(num, 1);
}
public Rational(int num, int den) {
this.num = num;
this.den = den;
}
public int getNum() {
return num;
}
public int getDen() {
return den;
}
public static Rational parse(String string) {
String[] split = splitS(string, ":");
return split.length > 1 ? Rational.R(Integer.parseInt(split[0]), Integer.parseInt(split[1])) : Rational.R(
Integer.parseInt(string), 1);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + den;
result = prime * result + num;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Rational other = (Rational) obj;
if (den != other.den)
return false;
if (num != other.num)
return false;
return true;
}
public int multiplyS(int val) {
return (int) (((long) num * val) / den);
}
public int divideS(int val) {
return (int) (((long) den * val) / num);
}
public int divideByS(int val) {
return num / (den * val);
}
public long multiplyLong(long val) {
return (num * val) / den;
}
public long divideLong(long val) {
return (den * val) / num;
}
public Rational flip() {
return new Rational(den, num);
}
public boolean smallerThen(Rational sec) {
return num * sec.den < sec.num * den;
}
public boolean greaterThen(Rational sec) {
return num * sec.den > sec.num * den;
}
public boolean smallerOrEqualTo(Rational sec) {
return num * sec.den <= sec.num * den;
}
public boolean greaterOrEqualTo(Rational sec) {
return num * sec.den >= sec.num * den;
}
public boolean equalsRational(Rational other) {
return num * other.den == other.num * den;
}
public Rational plus(Rational other) {
return reduce(num * other.den + other.num * den, den * other.den);
}
public RationalLarge plusLarge(RationalLarge other) {
return reduceLong(num * other.den + other.num * den, den * other.den);
}
public Rational minus(Rational other) {
return reduce(num * other.den - other.num * den, den * other.den);
}
public RationalLarge minusLarge(RationalLarge other) {
return reduceLong(num * other.den - other.num * den, den * other.den);
}
public Rational plusInt(int scalar) {
return new Rational(num + scalar * den, den);
}
public Rational minusInt(int scalar) {
return new Rational(num - scalar * den, den);
}
public Rational multiplyInt(int scalar) {
return new Rational(num * scalar, den);
}
public Rational divideInt(int scalar) {
return new Rational(den * scalar, num);
}
public Rational divideByInt(int scalar) {
return new Rational(num, den * scalar);
}
public Rational multiply(Rational other) {
return reduce(num * other.num, den * other.den);
}
public RationalLarge multiplyLarge(RationalLarge other) {
return reduceLong(num * other.num, den * other.den);
}
public Rational divide(Rational other) {
return reduce(other.num * den, other.den * num);
}
public RationalLarge divideLarge(RationalLarge other) {
return reduceLong(other.num * den, other.den * num);
}
public Rational divideBy(Rational other) {
return reduce(num * other.den, den * other.num);
}
public RationalLarge divideByLarge(RationalLarge other) {
return reduceLong(num * other.den, den * other.num);
}
public float scalar() {
return (float) num / den;
}
public int scalarClip() {
return num / den;
}
public static Rational reduce(int num, int den) {
int gcd = MathUtil.gcd(num, den);
return new Rational(num / gcd, den / gcd);
}
public static Rational reduceRational(Rational r) {
return reduce(r.getNum(), r.getDen());
}
}