Fixed definition of remainder and added missing copySign signature.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1449722 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2013-02-25 14:33:53 +00:00
parent 684a87be70
commit ccdf6bd680
5 changed files with 56 additions and 14 deletions

View File

@ -44,15 +44,17 @@ public interface ExtendedFieldElement<T> extends FieldElement<T> {
*/ */
T divide(double a); T divide(double a);
/** '%' operator. /** IEEE remainder operator.
* @param a right hand side parameter of the operator * @param a right hand side parameter of the operator
* @return this%a * @return this - n &times; a where n is the closest integer to this/a
* (the even integer is chosen for n if this/a is halfway between two integers)
*/ */
T remainder(double a); T remainder(double a);
/** '%' operator. /** IEEE remainder operator.
* @param a right hand side parameter of the operator * @param a right hand side parameter of the operator
* @return this%a * @return this - n &times; a where n is the closest integer to this/a
* (the even integer is chosen for n if this/a is halfway between two integers)
* @exception DimensionMismatchException if number of free parameters or orders are inconsistent * @exception DimensionMismatchException if number of free parameters or orders are inconsistent
*/ */
T remainder(T a) T remainder(T a)
@ -89,6 +91,15 @@ public interface ExtendedFieldElement<T> extends FieldElement<T> {
*/ */
T signum(); T signum();
/**
* Returns the instance with the sign of the argument.
* A NaN {@code sign} argument is treated as positive.
*
* @param sign the sign for the returned value
* @return the instance with the same sign as the {@code sign} argument
*/
T copySign(T sign);
/** /**
* Returns the instance with the sign of the argument. * Returns the instance with the sign of the argument.
* A NaN {@code sign} argument is treated as positive. * A NaN {@code sign} argument is treated as positive.

View File

@ -812,7 +812,7 @@ public class DSCompiler {
final double[] result, final int resultOffset) { final double[] result, final int resultOffset) {
// compute k such that lhs % rhs = lhs - k rhs // compute k such that lhs % rhs = lhs - k rhs
final double rem = lhs[lhsOffset] % rhs[rhsOffset]; final double rem = FastMath.IEEEremainder(lhs[lhsOffset], rhs[rhsOffset]);
final double k = FastMath.rint((lhs[lhsOffset] - rem) / rhs[rhsOffset]); final double k = FastMath.rint((lhs[lhsOffset] - rem) / rhs[rhsOffset]);
// set up value // set up value

View File

@ -336,7 +336,7 @@ public class DerivativeStructure implements ExtendedFieldElement<DerivativeStruc
/** {@inheritDoc} */ /** {@inheritDoc} */
public DerivativeStructure remainder(final double a) { public DerivativeStructure remainder(final double a) {
final DerivativeStructure ds = new DerivativeStructure(this); final DerivativeStructure ds = new DerivativeStructure(this);
ds.data[0] = ds.data[0] % a; ds.data[0] = FastMath.IEEEremainder(ds.data[0], a);
return ds; return ds;
} }
@ -401,6 +401,16 @@ public class DerivativeStructure implements ExtendedFieldElement<DerivativeStruc
FastMath.signum(data[0])); FastMath.signum(data[0]));
} }
/** {@inheritDoc} */
public DerivativeStructure copySign(final DerivativeStructure sign){
long m = Double.doubleToLongBits(data[0]);
long s = Double.doubleToLongBits(sign.data[0]);
if ((m >= 0 && s >= 0) || (m < 0 && s < 0)) { // Sign is currently OK
return this;
}
return negate(); // flip sign
}
/** {@inheritDoc} */ /** {@inheritDoc} */
public DerivativeStructure copySign(final double sign){ public DerivativeStructure copySign(final double sign){
long m = Double.doubleToLongBits(data[0]); long m = Double.doubleToLongBits(data[0]);

View File

@ -2568,9 +2568,19 @@ public class Dfp implements ExtendedFieldElement<Dfp> {
/** {@inheritDoc} /** {@inheritDoc}
* @since 3.2 * @since 3.2
*/ */
public Dfp copySign(final double sign) { public Dfp copySign(final Dfp s) {
long s = Double.doubleToLongBits(sign); if ((sign >= 0 && s.sign >= 0) || (sign < 0 && s.sign < 0)) { // Sign is currently OK
if ((sign >= 0 && s >= 0) || (sign < 0 && s < 0)) { // Sign is currently OK return this;
}
return negate(); // flip sign
}
/** {@inheritDoc}
* @since 3.2
*/
public Dfp copySign(final double s) {
long sb = Double.doubleToLongBits(s);
if ((sign >= 0 && sb >= 0) || (sign < 0 && sb < 0)) { // Sign is currently OK
return this; return this;
} }
return negate(); // flip sign return negate(); // flip sign
@ -2601,7 +2611,9 @@ public class Dfp implements ExtendedFieldElement<Dfp> {
* @since 3.2 * @since 3.2
*/ */
public Dfp rootN(final int n) { public Dfp rootN(final int n) {
return DfpMath.pow(this, getOne().divide(n)); return (sign >= 0) ?
DfpMath.pow(this, getOne().divide(n)) :
DfpMath.pow(negate(), getOne().divide(n)).negate();
} }
/** {@inheritDoc} /** {@inheritDoc}
@ -2747,7 +2759,7 @@ public class Dfp implements ExtendedFieldElement<Dfp> {
public Dfp tanh() { public Dfp tanh() {
final Dfp ePlus = DfpMath.exp(this); final Dfp ePlus = DfpMath.exp(this);
final Dfp eMinus = DfpMath.exp(negate()); final Dfp eMinus = DfpMath.exp(negate());
return ePlus.add(eMinus).divide(ePlus.subtract(eMinus)); return ePlus.subtract(eMinus).divide(ePlus.add(eMinus));
} }
/** {@inheritDoc} /** {@inheritDoc}

View File

@ -330,12 +330,12 @@ public class Decimal64 extends Number
/** {@inheritDoc} */ /** {@inheritDoc} */
public Decimal64 remainder(final double a) { public Decimal64 remainder(final double a) {
return new Decimal64(value % a); return new Decimal64(FastMath.IEEEremainder(value, a));
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public Decimal64 remainder(final Decimal64 a) { public Decimal64 remainder(final Decimal64 a) {
return new Decimal64(value % a.value); return new Decimal64(FastMath.IEEEremainder(value, a.value));
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
@ -368,6 +368,11 @@ public class Decimal64 extends Number
return new Decimal64(FastMath.signum(value)); return new Decimal64(FastMath.signum(value));
} }
/** {@inheritDoc} */
public Decimal64 copySign(final Decimal64 sign) {
return new Decimal64(FastMath.copySign(value, sign.value));
}
/** {@inheritDoc} */ /** {@inheritDoc} */
public Decimal64 copySign(final double sign) { public Decimal64 copySign(final double sign) {
return new Decimal64(FastMath.copySign(value, sign)); return new Decimal64(FastMath.copySign(value, sign));
@ -395,7 +400,11 @@ public class Decimal64 extends Number
/** {@inheritDoc} */ /** {@inheritDoc} */
public Decimal64 rootN(final int n) { public Decimal64 rootN(final int n) {
return new Decimal64(FastMath.pow(value, 1.0 / n)); if (value < 0) {
return new Decimal64(-FastMath.pow(-value, 1.0 / n));
} else {
return new Decimal64(FastMath.pow(value, 1.0 / n));
}
} }
/** {@inheritDoc} */ /** {@inheritDoc} */