首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java中BigNumber/BigFraction的实现

Java中BigNumber/BigFraction的实现
EN

Code Review用户
提问于 2023-05-29 19:57:34
回答 1查看 430关注 0票数 3

我已经创建了一个BigFraction替代BigIntegerBigDecimal。这个类的名称还没有完全确定下来。

最近,我完成了一门关于面向对象操作和文档的课程。我们了解了先决条件和后置条件、LSP、国家代表等等。我建这个项目是为了展示我努力的一些成果。我们特别注意确保这个类有很好的文档,因为Javadoc也是这个类的一个非常重要的部分。

我欢迎并邀请任何和所有的投入/批评/评论/等等。请不要抽打或限制/排除为简洁--我想要所有的反馈,并打算阅读每一个字。

最后,这里是它的GitHub,以防提交历史有助于提供反馈。这里没有未粘贴的东西(除非有一些git配置文件和包含此代码的jGRASP项目)。

https://github.com/davidalayachew/BigNumber

谢谢你的时间和帮助!

BigInteger.java

代码语言:javascript
复制
import java.math.BigInteger;
import java.util.Objects;

/** If you know BigInteger and BigDecimal, think of this as BigFraction. This class is immutable. */
public final class BigNumber
{

   /**
    *
    * The numerator.
    *
    * Can be any whole number.
    * Must always contain the negative symbol if the whole "BigNumber" is negative.
    * Cannot be null;
    *
    */
   private final BigInteger numerator;

   /**
    *
    * The denominator.
    *
    * Can be any whole number except for zero.
    * Must always be unsigned.
    * Cannot be null.
    *
    */
   private final BigInteger denominator;

   /**
    *
    * Constructor.
    *
    * @param param the new number.
    *
    */
   public BigNumber(long param)
   {
   
      this(BigInteger.valueOf(param), BigInteger.ONE);
   
   }

   /**
    *
    * Constructor.
    *
    * @param param the new number.
    * @throws NullPointerException if parameter is null
    *
    */
   public BigNumber(BigInteger param)
   {
   
      Objects.requireNonNull(param, "parameter cannot be null");
   
      this.numerator = param;
      this.denominator = BigInteger.ONE;
   
   }

   /**
    *
    * Constructor.
    *
    * @param numerator        the numerator.
    * @param denominator      the denominator.
    * @throws NullPointerException        if numerator or denominator is null
    * @throws IllegalArgumentException    if denominator is 0
    *
    */
   public BigNumber(BigInteger numerator, BigInteger denominator)
   {
   
      Objects.requireNonNull(numerator, "numerator cannot be null");
      Objects.requireNonNull(denominator, "denominator cannot be null");
   
      if (denominator.intValue() == 0)
      {
      
         throw new IllegalArgumentException("denominator cannot be 0");
      
      }
   
      this.numerator = isPositive(denominator) ? numerator : numerator.negate();
      this.denominator = denominator.abs();
   
   }

   /**
    *
    * Constructor.
    *
    * @param param the new number.
    * @throws NullPointerException if parameter is null
    *
    */
   public BigNumber(BigNumber param)
   {
   
      this(Objects.requireNonNull(param, "BigNumber cannot be null").numerator, param.denominator);
   
   }

   /**
    *
    * Returns the (signed) numerator.
    *
    * @return     the numerator.
    *
    */
   public BigInteger getNumerator()
   {
   
      return this.numerator;
   
   }

   /**
    *
    * Returns the (unsigned) denominator.
    *
    * @return     the denominator.
    *
    */
   public BigInteger getDenominator()
   {
   
      return this.denominator;
   
   }

   /**
    *
    * Returns an equivalent BigNumber, but with the sign changed from positive to negative, or vice versa.
    *
    * @return     a BigNumber that has had its sign flipped
    *
    */
   public BigNumber negate()
   {
   
      return this.multiply(-1);
   
   }

   /**
    *
    * Returns true if positive.
    *
    * @return     the result
    *
    */
   public boolean isPositive()
   {
   
      return isPositive(this.numerator);
   
   }

   /**
    *
    * Returns true if num is >0.
    *
    * @param num  the number we are checking the sign of
    * @return     boolean result
    *
    */
   private static boolean isPositive(BigInteger num)
   {
   
      return num.signum() > 0;
   
   }

   /**
    *
    * Method to simplify the numerator and denominator before creating a BigNumber from them.
    *
    * Numerator cannot be null.
    * Denominator cannot be null.
    * Denominator cannot be 0.
    *
    * @param numerator     the numerator
    * @param denominator   the denominator
    * @return              the simplified BigNumber
    *
    */
   private static BigNumber simplify(BigInteger numerator, BigInteger denominator)
   {
   
      final var gcd = numerator.gcd(denominator);
   
      return new BigNumber(numerator.divide(gcd), denominator.divide(gcd));
   
   }

   /**
    *
    * Standard add function.
    *
    * @param param      the number to add.
    * @return           The answer.
    *
    */
   public BigNumber add(long param)
   {
   
      return this.add(new BigNumber(param));
   
   }

   /**
    *
    * Standard add function.
    *
    * @param param      the number to add.
    * @return           The answer.
    * @throws NullPointerException if parameter is null
    *
    */
   public BigNumber add(BigNumber param)
   {
   
      Objects.requireNonNull(param, "parameter cannot be null");
   
      BigInteger resultNumerator;
      BigInteger resultDenominator;
   
      if (this.denominator.equals(param.getDenominator()))
      {
      
         resultNumerator = this.numerator.add(param.getNumerator());
         resultDenominator = BigInteger.ONE;
      
      }
      
      else
      {
      
         //our goal here is to end up with a shared denominator
         //So, in order to accomplish that, we will need to do
         //that cross multiplication thing that you do to end
         //up with the same denominator
      
         BigInteger numerator1 = this.numerator.multiply(param.denominator);
         BigInteger numerator2 = param.numerator.multiply(this.denominator);
      
         resultNumerator = numerator1.add(numerator2);
         resultDenominator = param.getDenominator().multiply(this.getDenominator());
      
      }
   
      //simplify before we return. We don't want to waste memory when the number can be simplified into something smaller.
      return simplify(resultNumerator, resultDenominator);
   
   }

   /**
    *
    * Standard subtract function.
    *
    * @param param      the number to subtract from this.
    * @return           The answer.
    *
    */
   public BigNumber subtract(long param)
   {
   
      return this.add(new BigNumber(param * -1));
   
   }

   /**
    *
    * Standard subtract function.
    *
    * @param param      the number to subtract from this.
    * @return           The answer.
    *
    */
   public BigNumber subtract(BigNumber param)
   {
   
      Objects.requireNonNull(param, "BigNumber cannot be null");
   
      return this.add(param.negate());
   
   }

   /**
    *
    * Standard multiply function.
    *
    * @param param      the number to multiply.
    * @return           The answer.
    *
    */
   public BigNumber multiply(long param)
   {
   
      return this.multiply(new BigNumber(param));
   
   }

   /**
    *
    * Standard multiply function.
    *
    * @param param      the number to multiply.
    * @return           The answer.
    * @throws NullPointerException if parameter is null
    *
    */
   public BigNumber multiply(BigNumber param)
   {
   
      Objects.requireNonNull(param, "parameter cannot be null");
   
      BigInteger resultNumerator = this.numerator.multiply(param.numerator);
      BigInteger resultDenominator = this.denominator.multiply(param.denominator);
   
      return simplify(resultNumerator, resultDenominator);
   
   }

   /**
    *
    * Standard divide function.
    *
    * @param param      the number to divide this by.
    * @return           The answer.
    * @throws IllegalArgumentException if param == 0
    *
    */
   public BigNumber divide(long param)
   {
   
      if (param == 0) {
         throw new IllegalArgumentException("param cannot be 0"); }
   
      return this.divide(new BigNumber(param));
   
   }

   /**
    *
    * Standard divide function.
    *
    * @param param      the number to divide this by.
    * @return           The answer.
    * @throws NullPointerException if parameter is null
    * @throws IllegalArgumentException if param == 0
    *
    */
   public BigNumber divide(BigNumber param)
   {
   
      Objects.requireNonNull(param, "parameter cannot be null");
   
      if (param.numerator.equals(BigInteger.ZERO)) {
         throw new IllegalArgumentException("param cannot be 0"); }
   
      return this.multiply(new BigNumber(param.denominator, param.numerator));
   
   }

   /** {@inheritDoc} */
   public String toString()
   {
   
      return this.numerator + " / " + this.denominator;
   
   }

}
EN

回答 1

Code Review用户

发布于 2023-05-30 12:46:21

  • 分母不能是zero.,你当然可以选择这样做。您也可以选择允许分母为零。在这种情况下,您可以表示值PositiveInfinity、NegativeInfinity和NaN。你不需要这么做。这取决于你用它做什么,我想。这将使您的类变得更加复杂,因为您必须在每个方法中检查零分母。
  • 公共布尔值isPositive()为什么是isPositive()而不是isNegative()或isZero()?这太奇怪了。您所需要的只是一个signum()方法。
  • 实现类似的接口以及等于()和hashCode()是有意义的。

(其他问题已在其他答覆中提及)

票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/285231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档