⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 floatmul.java

📁 浮点数加减乘除
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
     * @param  val <tt>double</tt> to convert to a <tt>BigDecimal</tt>.     * @return a <tt>BigDecimal</tt> whose value is equal to or approximately     *         equal to the value of <tt>val</tt>.     * @throws NumberFormatException if <tt>val</tt> is infinite or NaN.     * @since  1.5     */    public static BigDecimal valueOf(double val) {        // Reminder: a zero double returns '0.0', so we cannot fastpath        // to use the constant ZERO.  This might be important enough to        // justify a factory approach, a cache, or a few private        // constants, later.        return new BigDecimal(Double.toString(val));    }    // Arithmetic Operations    /**     * Returns a <tt>BigDecimal</tt> whose value is <tt>(this +     * augend)</tt>, and whose scale is <tt>max(this.scale(),     * augend.scale())</tt>.     *     * @param  augend value to be added to this <tt>BigDecimal</tt>.     * @return <tt>this + augend</tt>     */    public BigDecimal add(BigDecimal augend) {        BigDecimal arg[] = {this, augend};        matchScale(arg);	long x = arg[0].intCompact;	long y = arg[1].intCompact;	// Might be able to do a more clever check incorporating the	// inflated check into the overflow computation.	if (x != INFLATED && y != INFLATED) {	    long sum = x + y;	    /*	     * If the sum is not an overflowed value, continue to use	     * the compact representation.  if either of x or y is	     * INFLATED, the sum should also be regarded as an	     * overflow.  See "Hacker's Delight" section 2-12 for	     * explanation of the overflow test.	     */	    if ( (((sum ^ x) & (sum ^ y)) >> 63) == 0L )	// not overflowed		return BigDecimal.valueOf(sum, arg[0].scale);	}        return new BigDecimal(arg[0].inflate().intVal.add(arg[1].inflate().intVal), arg[0].scale);    }    /**     * Returns a <tt>BigDecimal</tt> whose value is <tt>(this + augend)</tt>,     * with rounding according to the context settings.     *     * If either number is zero and the precision setting is nonzero then     * the other number, rounded if necessary, is used as the result.     *     * @param  augend value to be added to this <tt>BigDecimal</tt>.     * @param  mc the context to use.     * @return <tt>this + augend</tt>, rounded as necessary.     * @throws ArithmeticException if the result is inexact but the     *         rounding mode is <tt>UNNECESSARY</tt>.     * @since  1.5     */    public BigDecimal add(BigDecimal augend, MathContext mc) {        if (mc.precision == 0)            return add(augend);        BigDecimal lhs = this;	// Could optimize if values are compact	this.inflate();	augend.inflate();	        // If either number is zero then the other number, rounded and        // scaled if necessary, is used as the result.	{	    boolean lhsIsZero = lhs.signum() == 0;	    boolean augendIsZero = augend.signum() == 0;	    if (lhsIsZero || augendIsZero) {		int preferredScale = Math.max(lhs.scale(), augend.scale());		BigDecimal result;		// Could use a factory for zero instead of a new object		if (lhsIsZero && augendIsZero)		    return new BigDecimal(BigInteger.ZERO, 0, preferredScale);		result = lhsIsZero ? augend.doRound(mc) : lhs.doRound(mc);		if (result.scale() == preferredScale) 		    return result;		else if (result.scale() > preferredScale) 		    return new BigDecimal(result.intVal, result.intCompact, result.scale).			stripZerosToMatchScale(preferredScale);		else { // result.scale < preferredScale		    int precisionDiff = mc.precision - result.precision();		    int scaleDiff     = preferredScale - result.scale();		    if (precisionDiff >= scaleDiff)			return result.setScale(preferredScale); // can achieve target scale		    else			return result.setScale(result.scale() + precisionDiff);		} 	    }	}        long padding = (long)lhs.scale - augend.scale;        if (padding != 0) {        // scales differ; alignment needed            BigDecimal arg[] = preAlign(lhs, augend, padding, mc);            matchScale(arg);            lhs    = arg[0];            augend = arg[1];        }		return new BigDecimal(lhs.inflate().intVal.add(augend.inflate().intVal),			      lhs.scale).doRound(mc);    }    /**     * Returns an array of length two, the sum of whose entries is     * equal to the rounded sum of the {@code BigDecimal} arguments.     *     * <p>If the digit positions of the arguments have a sufficient     * gap between them, the value smaller in magnitude can be     * condensed into a &quot;sticky bit&quot; and the end result will     * round the same way <em>if</em> the precision of the final     * result does not include the high order digit of the small     * magnitude operand.     *     * <p>Note that while strictly speaking this is an optimization,     * it makes a much wider range of additions practical.     *      * <p>This corresponds to a pre-shift operation in a fixed     * precision floating-point adder; this method is complicated by     * variable precision of the result as determined by the     * MathContext.  A more nuanced operation could implement a     * &quot;right shift&quot; on the smaller magnitude operand so     * that the number of digits of the smaller operand could be     * reduced even though the significands partially overlapped.     */    private BigDecimal[] preAlign(BigDecimal lhs, BigDecimal augend,				  long padding, MathContext mc) {	assert padding != 0;	BigDecimal big;	BigDecimal small;		if (padding < 0) {     // lhs is big;   augend is small	    big   = lhs;	    small = augend;	} else {               // lhs is small; augend is big	    big   = augend;	    small = lhs;	}	/*	 * This is the estimated scale of an ulp of the result; it	 * assumes that the result doesn't have a carry-out on a true	 * add (e.g. 999 + 1 => 1000) or any subtractive cancellation	 * on borrowing (e.g. 100 - 1.2 => 98.8)	 */	long estResultUlpScale = (long)big.scale - big.precision() + mc.precision;	/*	 * The low-order digit position of big is big.scale().  This	 * is true regardless of whether big has a positive or	 * negative scale.  The high-order digit position of small is	 * small.scale - (small.precision() - 1).  To do the full	 * condensation, the digit positions of big and small must be	 * disjoint *and* the digit positions of small should not be	 * directly visible in the result.	 */	long smallHighDigitPos = (long)small.scale - small.precision() + 1;	if (smallHighDigitPos > big.scale + 2 && 	 // big and small disjoint	    smallHighDigitPos > estResultUlpScale + 2) { // small digits not visible	    small = BigDecimal.valueOf(small.signum(),				       this.checkScale(Math.max(big.scale, estResultUlpScale) + 3));	}		// Since addition is symmetric, preserving input order in	// returned operands doesn't matter	BigDecimal[] result = {big, small};	return result;    }    /**     * Returns a <tt>BigDecimal</tt> whose value is <tt>(this -     * subtrahend)</tt>, and whose scale is <tt>max(this.scale(),     * subtrahend.scale())</tt>.     *     * @param  subtrahend value to be subtracted from this <tt>BigDecimal</tt>.     * @return <tt>this - subtrahend</tt>     */    public BigDecimal subtract(BigDecimal subtrahend) {        BigDecimal arg[] = {this, subtrahend};        matchScale(arg);	long x = arg[0].intCompact;	long y = arg[1].intCompact;	// Might be able to do a more clever check incorporating the	// inflated check into the overflow computation.	if (x != INFLATED && y != INFLATED) {	    long difference = x - y;	    /*	     * If the difference is not an overflowed value, continue	     * to use the compact representation.  if either of x or y	     * is INFLATED, the difference should also be regarded as	     * an overflow.  See "Hacker's Delight" section 2-12 for	     * explanation of the overflow test.	     */	    if ( ((x ^ y) & (difference ^ x) ) >> 63 == 0L )	// not overflowed		return BigDecimal.valueOf(difference, arg[0].scale);	}        return new BigDecimal(arg[0].inflate().intVal.subtract(arg[1].inflate().intVal),                              arg[0].scale);    }    /**     * Returns a <tt>BigDecimal</tt> whose value is <tt>(this - subtrahend)</tt>,     * with rounding according to the context settings.     *     * If <tt>subtrahend</tt> is zero then this, rounded if necessary, is used as the     * result.  If this is zero then the result is <tt>subtrahend.negate(mc)</tt>.     *     * @param  subtrahend value to be subtracted from this <tt>BigDecimal</tt>.     * @param  mc the context to use.     * @return <tt>this - subtrahend</tt>, rounded as necessary.     * @throws ArithmeticException if the result is inexact but the     *         rounding mode is <tt>UNNECESSARY</tt>.     * @since  1.5     */    public BigDecimal subtract(BigDecimal subtrahend, MathContext mc) {        if (mc.precision == 0)            return subtract(subtrahend);        // share the special rounding code in add()	this.inflate();	subtrahend.inflate();        BigDecimal rhs = new BigDecimal(subtrahend.intVal.negate(), subtrahend.scale);        rhs.precision = subtrahend.precision;        return add(rhs, mc);    }    /**     * Returns a <tt>BigDecimal</tt> whose value is <tt>(this &times;     * multiplicand)</tt>, and whose scale is <tt>(this.scale() +     * multiplicand.scale())</tt>.     *     * @param  multiplicand value to be multiplied by this <tt>BigDecimal</tt>.     * @return <tt>this * multiplicand</tt>     */    public BigDecimal multiply(BigDecimal multiplicand) {	long x = this.intCompact;	long y = multiplicand.intCompact;	int productScale = checkScale((long)scale+multiplicand.scale);	// Might be able to do a more clever check incorporating the	// inflated check into the overflow computation.	if (x != INFLATED && y != INFLATED) {	    /*	     * If the product is not an overflowed value, continue	     * to use the compact representation.  if either of x or y	     * is INFLATED, the product should also be regarded as	     * an overflow.  See "Hacker's Delight" section 2-12 for	     * explanation of the overflow test.	     */	    long product = x * y;	    if ( !(y != 0L && product/y != x)  )	// not overflowed		return BigDecimal.valueOf(product, productScale);	}        BigDecimal result = new BigDecimal(this.inflate().intVal.multiply(multiplicand.inflate().intVal), productScale);        return result;    }    /**     * Returns a <tt>BigDecimal</tt> whose value is <tt>(this &times;     * multiplicand)</tt>, with rounding according to the context settings.     *     * @param  multiplicand value to be multiplied by this <tt>BigDecimal</tt>.     * @param  mc the context to use.     * @return <tt>this * multiplicand</tt>, rounded as necessary.     * @throws ArithmeticException if the result is inexact but the     *         rounding mode is <tt>UNNECESSARY</tt>.     * @since  1.5     */    public BigDecimal multiply(BigDecimal multiplicand, MathContext mc) {        if (mc.precision == 0)            return multiply(multiplicand);        BigDecimal lhs = this;        return lhs.inflate().multiply(multiplicand.inflate()).doRound(mc);    }    /**     * Returns a <tt>BigDecimal</tt> whose value is <tt>(this /     * divisor)</tt>, and whose scale is as specified.  If rounding must     * be performed to generate a result with the specified scale, the     * specified rounding mode is applied.     *      * <p>The new {@link #divide(BigDecimal, int, RoundingMode)} method     * should be used in preference to this legacy method.     *      * @param  divisor value by which this <tt>BigDecimal</tt> is to be divided.     * @param  scale scale of the <tt>BigDecimal</tt> quotient to be returned.     * @param  roundingMode rounding mode to apply.     * @return <tt>this / divisor</tt>     * @throws ArithmeticException if <tt>divisor</tt> is zero,     *         <tt>roundingMode==ROUND_UNNECESSARY</tt> and     *         the specified scale is insufficient to represent the result     *         of the division exactly.     * @throws IllegalArgumentException if <tt>roundingMode</tt> does not     *         represent a valid rounding mode.     * @see    #ROUND_UP     * @see    #ROUND_DOWN     * @see    #ROUND_CEILING     * @see    #ROUND_FLOOR     * @see    #ROUND_HALF_UP     * @see    #ROUND_HALF_DOWN     * @see    #ROUND_HALF_EVEN     * @see    #ROUND_UNNECESSARY     */    public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) {	/* 	 * IMPLEMENTATION NOTE: This method *must* return a new object	 * since dropDigits uses divide to generate a value whose	 * scale is then modified.	 */        if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)            throw new IllegalArgumentException("Invalid rounding mode");        /*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -