1. 程式人生 > >Algs4-1.2.17有理數實現的健壯性

Algs4-1.2.17有理數實現的健壯性

final als .com sce oid printf 啟用 detail 開發

1.2.17有理數實現的健壯性。在Rational(請見練習1.2.16)的開發中使用斷言來防止溢出。
答:在命令行使用:java -ea 文件名 啟用斷言功能。(估計是單次啟用斷言)
技術分享圖片
public class Rational
{
private final long myNumerator;
private final long myDenominator;

private long gcd(long p,long q)
{
if (q==0) return p;
return gcd(q,p%q);
}

public Rational(long numerator, long denominator)
{
assert denominator!=0:"denominator is zero.";
assert numerator>Long.MIN_VALUE:"numberator is overflow.";
assert denominator>Long.MIN_VALUE:"denominator is overflow.";

long gcdValue=gcd(numerator,denominator);
myNumerator=numerator/gcdValue;
myDenominator=denominator/gcdValue;
}

public long Numberator()
{
return myNumerator;
}

public long Denominator()
{
return myDenominator;
}

public Rational plus(Rational b)
{
long gcdValue=gcd(this.Denominator(),b.Denominator());
long n=b.Denominator()/gcdValue;
assert Long.MIN_VALUE/n<=this.Numberator() && this.Numberator()

<=Long.MAX_VALUE/n:"overflow";
n=this.Numberator()*n;
//
long m=this.Denominator()/gcdValue;
assert Long.MIN_VALUE/m<=b.Numberator() && b.Numberator()<=

Long.MAX_VALUE/n:"overflow";
m=b.Numberator()*m;
//

assert n>=0 && m>=0 && n<=Long.MAX_VALUE-m:"overflow";
assert n<0 && m<0 && Long.MIN_VALUE-m<=n:"overflow";
assert (n<0 && m>0 || n>0 && m<0) && Long.MIN_VALUE-m<=n &&

n<=Long.MAX_VALUE-m:"overflow";
n=n+m;
////

long d=b.Denominator()/gcdValue;
assert Long.MIN_VALUE/n<=this.Denominator() && this.Denominator()

<=Long.MAX_VALUE/n :"overflow";
d=d*this.Denominator();
//
gcdValue=gcd(d,n);
n=n/gcdValue;
d=d/gcdValue;
return new Rational(n,d);
}

public Rational minus(Rational b)
{
long gcdValue=gcd(this.Denominator(),b.Denominator());
long n=b.Denominator()/gcdValue;
assert Long.MIN_VALUE/n<=this.Numberator() && this.Numberator()

<=Long.MAX_VALUE/n:"overflow";
n=this.Numberator()*n;
//
long m=this.Denominator()/gcdValue;
assert Long.MIN_VALUE/m<=b.Numberator() && b.Numberator()<=

Long.MAX_VALUE/n:"overflow";
m=b.Numberator()*m;
//

assert (n>0 && m<0) && n<=Long.MAX_VALUE+m:"overflow";
assert (n<0 && m>0) && n<=Long.MIN_VALUE-m:"overflow";
n=n-m;
////

long d=b.Denominator()/gcdValue;
assert Long.MIN_VALUE/n<=this.Denominator() && this.Denominator()

<=Long.MAX_VALUE/n :"overflow";
d=d*this.Denominator();
//
gcdValue=gcd(d,n);
n=n/gcdValue;
d=d/gcdValue;
return new Rational(n,d);
}

public Rational times(Rational b)
{
long gcdValue1=gcd(this.Numberator(),b.Denominator());
long gcdValue2=gcd(this.Denominator(),b.Numberator());
//
long n=this.Numberator()/gcdValue1;
long m=b.Numberator()/gcdValue2;
assert Long.MIN_VALUE/n<=m && m <=Long.MAX_VALUE/n:"overflow";
n=n*m;
//
long d=this.Denominator()/gcdValue2;
long k=b.Denominator()/gcdValue1;
assert Long.MIN_VALUE/d<=k && k <=Long.MAX_VALUE/d:"overflow";
d=d*k;
return new Rational(n,d);
}

public Rational divides(Rational b)
{
long gcdValue1=gcd(this.Numberator(),b.Numberator());
long gcdValue2=gcd(this.Denominator(),b.Denominator());
//
long n=this.Numberator()/gcdValue1;
long m=b.Denominator()/gcdValue2;
assert Long.MIN_VALUE/n<=m && m <=Long.MAX_VALUE/n:"overflow";
n=n*m;
//
long d=this.Denominator()/gcdValue2;
long k=b.Numberator()/gcdValue1;
assert Long.MIN_VALUE/d<=k && k <=Long.MAX_VALUE/d:"overflow";
d=d*k;
return new Rational(n,d);
}

public boolean equals(Rational that)
{
if(this==that) return true;
if(that==null) return false;
if(this.Numberator()!=that.Numberator()) return false;
if(this.Denominator()!=that.Denominator()) return false;
return true;
}

public String toString()
{
return this.Numberator()+"/"+this.Denominator();
}

public static void main(String[] args)
{
long Numberator=Long.MIN_VALUE+1;
long Denominator=Long.MAX_VALUE-1;

// long Numberator=Long.parseLong(args[0]);
// long Denominator=Long.parseLong(args[1]);

Rational r1=new Rational(Numberator,Denominator);
Rational r2=new Rational(Numberator,Denominator);
//=
StdOut.printf("r1=%-7s r2=%-7s r1=rs2 is:%s\n",r1.toString

(),r2.toString(),r1.equals(r2));
//+
StdOut.printf("r1=%-7s r2=%-7s r1+rs2=%-7s\n",r1.toString(),r2.toString

(),r1.plus(r2));
//-
StdOut.printf("r1=%-7s r2=%-7s r1-rs2=%-7s\n",r1.toString(),r2.toString

(),r1.minus(r2));
//*
StdOut.printf("r1=%-7s r2=%-7s r1*rs2=%-7s\n",r1.toString(),r2.toString

(),r1.times(r2));
// /
StdOut.printf("r1=%-7s r2=%-7s r1/rs2=%-7s\n",r1.toString(),r2.toString

(),r1.divides(r2));
}
}

Algs4-1.2.17有理數實現的健壯性