2014-10-19 33 views
0

对于类,我必须编写一个方法来检查将某个有理数与整数相乘是否会导致溢出。如何缩短检查乘法是否溢出的方法

我已经写了下面的代码和它的作品,但我有一种感觉这可能是短,但我不知道如何:

/** 
* A method for multiplying a rational number with a given number 
*/ 
public Rational multiply(long factor) { 
    try { 
     this.numerator = Math.multiplyExact(this.getNumerator(), factor); 
     return this; 
    } catch (ArithmeticException e) { 
     try { 
      this.numerator = Math.multiplyExact(Math.multiplyExact(this.getNumerator(),this.getNumerator()), factor); 
      this.denominator = this.denominator * this.denominator; 
      return this; 
     } catch (ArithmeticException e1) { 
      try { 
       this.numerator = Math.multiplyExact(Math.multiplyExact(this.getNumerator(),this.getNumerator()),Math.multiplyExact(factor, factor)); 
       this.denominator = this.denominator * this.denominator * this.denominator; 
       return this; 
      } catch (ArithmeticException e2) { 
       System.out.println("Overflow"); 
       return null; 
      } 
     } 
    } 
} 

的方法执行以下操作: A =分子,B =分母中,f =因子

  • 如果使用 “α* F” 不溢出不是返回(A * F)导致/ b
  • 如果它溢出比检查的 “aa * F” 溢出,如果它不不是回报(aa * f)/ bb
  • 如果它溢出比检查“AA * FF”溢出,如果它不高于收益率(AA * FF)/ BBB
+1

为什么你认为乘以一个数字溢出与另一个数字它不会溢出? – 2014-10-19 12:35:12

+0

您可以检查乘法的结果是否小于输入值。如果这是真的,则发生溢出。这不会处理所有情况,但你也可以对这个因素进行一些检查。就像Integer.MAX_VALUE%rational < factor -->溢出 – user 2014-10-19 12:53:15

+0

我认为用BigIntegers你不必担心溢出太多,所以除非有其他约束(比如性能问题),否则我会使用它们。 – 2014-10-19 20:49:57

回答

0

随着Integer.MAX_VALUE % d你会得到你多少次乘d数以获得最大值,如果这个值更小,那么你的因子乘法将溢出。

public Rational multiply(Long factor) { 
    double d = this.numerator/(double) this.denumerator; 
    if(Integer.MAX_VALUE % d < factor){ 
     //overflow 
    } else if (this.numerator * factor < this.numerator){ 
     //overflow 
    }else{ 
     this.numerator *= factor; 
    } 
} 

编辑︰如果您的Rational对象表示-1和1之间的值您可以确保没有溢出将发生。

+0

Java8中的Math#multiplyExact(http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#multiplyExact-long-long-)有什么问题?我认为这似乎是一个不错的选择。 – 2014-10-19 20:47:29

+0

@GáborBakosTrue!但我认为num和denom被存储为int,并且他希望与long相乘。所以当使用multiplyExact时,TO必须在multiplyExact(int,int)或multiplyExact(long,long)之间进行选择。 – user 2014-10-19 20:52:13