13.18 (Use the Rational class)
Write a program that computes the following
summation series using the Rational class:
You will discover that the output is incorrect because of integer overflow (too large).
To fix this problem, see Programming Exercise 13.15.
Write a program that computes the following
summation series using the Rational class:
You will discover that the output is incorrect because of integer overflow (too large).
To fix this problem, see Programming Exercise 13.15.
import java.math.BigDecimal; import java.math.RoundingMode; public class BigRational extends Number implements Comparable<BigRational> { // Data fields for numerator and denominator private BigDecimal numerator = BigDecimal.ZERO; private BigDecimal denominator = BigDecimal.ONE; /** Construct a rational with default properties */ public BigRational() { this(BigDecimal.ZERO, BigDecimal.ONE); } /** Construct a rational with specified numerator and denominator */ public BigRational(BigDecimal numerator, BigDecimal denominator) { BigDecimal gcd = gcd(numerator, denominator); this.numerator = ((denominator.compareTo(BigDecimal.ZERO) > 0) ? BigDecimal.ONE : new BigDecimal(-1)).multiply(numerator).divide(gcd); this.denominator = denominator.abs().divide(gcd); } public BigRational(String decimal) { int index = (decimal.contains(".")) ? decimal.indexOf('.') : decimal.indexOf('/'); BigDecimal d; BigDecimal n; // if string is in decimal form if (decimal.contains(".")) { int power = decimal.substring(index + 1, decimal.length()).length(); d = new BigDecimal(Math.pow(10,power)); n = new BigDecimal(new StringBuilder(decimal).deleteCharAt(index).toString()); } else { // if string contains '/' n = new BigDecimal(decimal.substring(0, index)); d = new BigDecimal(decimal.substring(index + 1, decimal.length())); } BigDecimal gcd = gcd(n, d); this.numerator = ((d.compareTo(BigDecimal.ZERO) > 0) ? BigDecimal.ONE : new BigDecimal(-1)).multiply(n).divide(gcd); this.denominator = d.abs().divide(gcd); } /** Find GCD of two numbers */ private static BigDecimal gcd(BigDecimal n, BigDecimal d) { BigDecimal n1 = n.abs(); BigDecimal n2 = d.abs(); BigDecimal remainder = n1.remainder(n2); while (remainder.compareTo(BigDecimal.ZERO) > 0) { n1 = n2; n2 = remainder; remainder = n1.remainder(n2); } return n2; } /** Return numerator */ public BigDecimal getNumerator() { return numerator; } /** Return denominator */ public BigDecimal getDenominator() { return denominator; } /** Add a rational number to this rational */ public BigRational add(BigRational secondBigRational) { BigDecimal n1 = numerator.multiply(secondBigRational.getDenominator()); BigDecimal n2 = denominator.multiply(secondBigRational.getNumerator()); BigDecimal n = n1.add(n2); BigDecimal d = denominator.multiply(secondBigRational.getDenominator()); return new BigRational(n, d); } /** Subtract a rational number from this rational */ public BigRational subtract(BigRational secondBigRational) { BigDecimal n1 = numerator.multiply(secondBigRational.getDenominator()); BigDecimal n2 = denominator.multiply(secondBigRational.getNumerator()); BigDecimal n = n1.subtract(n2); BigDecimal d = denominator.multiply(secondBigRational.getDenominator()); return new BigRational(n, d); } /** Multiply a rational number to this rational */ public BigRational multiply(BigRational secondBigRational) { BigDecimal n = numerator.multiply(secondBigRational.getNumerator()); BigDecimal d = denominator.multiply(secondBigRational.getDenominator()); return new BigRational(n, d); } /** Divide a rational number from this rational */ public BigRational divide(BigRational secondBigRational) { BigDecimal n = numerator.multiply(secondBigRational.getDenominator()); BigDecimal d = denominator.multiply(secondBigRational.numerator); return new BigRational(n, d); } @Override public String toString() { if (denominator.equals(BigDecimal.ONE)) return numerator + ""; else return numerator + "/" + denominator; } @Override // Override the equals method in the Object class public boolean equals(Object other) { if ((this.subtract((BigRational)(other))).getNumerator().equals(BigDecimal.ZERO)) return true; else return false; } @Override // Implement the abstract intValue method in Number public int intValue() { return (int)doubleValue(); } @Override // Implement the abstract floatValue method in Number public float floatValue() { return (float)doubleValue(); } @Override // Implement the doubleValue method in Number public double doubleValue() { return numerator.divide(denominator).doubleValue(); } public BigDecimal bigDecimalDouble() { return numerator.divide(denominator, 100, RoundingMode.HALF_DOWN); } @Override // Implement the abstract longValue method in Number public long longValue() { return (long)doubleValue(); } @Override // Implement the compareTo method in Comparable public int compareTo(BigRational o) { if (this.subtract(o).getNumerator().compareTo(BigDecimal.ZERO) > 0) return 1; else if (this.subtract(o).getNumerator().compareTo(BigDecimal.ZERO) < 0) return -1; else return 0; } }
public class Rational extends Number implements Comparable<Rational> { // Data fields for numerator and denominator private long[] r = new long[2]; private static int NUMERATOR = 0; private static int DENOMINATOR = 1; /** Default constructor */ public Rational() { this(0, 1); } /** Construct a rational with specified numerator and denominator */ public Rational(long numerator, long denominator) { long gcd = gcd(numerator, denominator); r[NUMERATOR] = ((denominator > 0) ? 1 : -1) * numerator / gcd; r[DENOMINATOR] = Math.abs(denominator) / gcd; } /** Find GCD of two numbers */ private long gcd(long n, long d) { long t1 = Math.abs(n); long t2 = Math.abs(d); long remainder = t1 % t2; while (remainder != 0) { t1 = t2; t2 = remainder; remainder = t1%t2; } return t2; } /** Return numerator */ public long getNumerator() { return r[NUMERATOR]; } /** Return denominator */ public long getDenominator() { return r[DENOMINATOR]; } /** Add a rational number to this rational */ public Rational add(Rational secondRational) { long n = r[NUMERATOR] * secondRational.getDenominator() + r[DENOMINATOR] * secondRational.getNumerator(); long d = r[DENOMINATOR] * secondRational.getDenominator(); return new Rational(n, d); } /** Subtract a rational number from this rational */ public Rational subtract(Rational secondRational) { long n = r[NUMERATOR] * secondRational.getDenominator() - r[DENOMINATOR] * secondRational.getNumerator(); long d = r[DENOMINATOR] * secondRational.getDenominator(); return new Rational(n, d); } /** Multiply a rational number to this rational */ public Rational multiply(Rational secondRational) { long n = r[NUMERATOR] * secondRational.getNumerator(); long d = r[DENOMINATOR] * secondRational.getDenominator(); return new Rational(n, d); } /** Divide a rational number from this rational */ public Rational divide(Rational secondRational) { long n = r[NUMERATOR] * secondRational.getDenominator(); long d = r[DENOMINATOR] * secondRational.r[NUMERATOR]; return new Rational(n, d); } @Override public String toString() { if (r[DENOMINATOR] == 1) return r[NUMERATOR] + ""; else return r[NUMERATOR] + "/" + r[DENOMINATOR]; } /** Override the equals method in the Object class */ public boolean equals(Object parm1) { return (this.subtract((Rational) (parm1))).getNumerator() == 0; } /** Override the hashCode method in the Object class */ public int hashCode() { return new Double(this.doubleValue()).hashCode(); } /** Override the abstract intValue method in java.lang.Number */ public int intValue() { return (int)doubleValue(); } /** Override the abstract floatValue method in java.lang.Number */ public float floatValue() { return (float)doubleValue(); } /** Override the doubleValue method in java.lang.Number */ public double doubleValue() { return r[NUMERATOR] * 1.0 / r[DENOMINATOR]; } /** Override the abstract longValue method in java.lang.Number */ public long longValue() { return (long)doubleValue(); } @Override public int compareTo(Rational o) { if ((this.subtract(o)).getNumerator() > 0) return 1; else if ((this.subtract(o)).getNumerator() < 0) return -1; else return 0; } }
import java.math.BigDecimal; public class Exercise_18 { public static void main(String[] args) { // using rational class Rational total = new Rational(); for (int i = 1; i < 100; i++) { total = total.add(new Rational(i, i + 1)); if (i < 10) { System.out.println("total = " + total); } } System.out.println(total + " = " + total.doubleValue()); // using BigRational class BigRational r = new BigRational( BigDecimal.ZERO, new BigDecimal(1)); for (int i = 1; i < 100; i++) { r = r.add(new BigRational(new BigDecimal(i), new BigDecimal(i + 1))); if (i < 10) { System.out.println("r = " + r); } } System.out.println("BigRational total = " + r); System.out.println("BigRational decimal form = " + r.bigDecimalDouble()); } }
No comments:
Post a Comment