Algs4-1.2.17有理数实现的健壮性

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));
    }
}
posted @ 2018-10-25 11:49  修电脑的龙生  阅读(207)  评论(0编辑  收藏  举报