MATH-689
Implemented "copySign" for integral types. Removed redundant "indicator" functions. Moved "indicator" tests (for floating point arguments) to "FastMathTest", as the corresponding "copySign" methods are in "FastMath". git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1206274 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ec5d9d3772
commit
a050013f44
|
@ -921,7 +921,7 @@ public class Complex implements FieldElement<Complex>, Serializable {
|
|||
* where <ul>
|
||||
* <li>{@code |a| = }{@link Math#abs}(a)</li>
|
||||
* <li>{@code |a + bi| = }{@link Complex#abs}(a + bi)</li>
|
||||
* <li>{@code sign(b) = }{@link MathUtils#indicator}(b)
|
||||
* <li>{@code sign(b) = }{@link FastMath#copySign(double,double) copySign(1d, b)}
|
||||
* </ul>
|
||||
* <br/>
|
||||
* Returns {@link Complex#NaN} if either real or imaginary part of the
|
||||
|
@ -957,7 +957,7 @@ public class Complex implements FieldElement<Complex>, Serializable {
|
|||
return createComplex(t, imaginary / (2.0 * t));
|
||||
} else {
|
||||
return createComplex(FastMath.abs(imaginary) / (2.0 * t),
|
||||
MathUtils.indicator(imaginary) * t);
|
||||
FastMath.copySign(1d, imaginary) * t);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -82,77 +82,6 @@ public final class MathUtils {
|
|||
return Arrays.hashCode(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* For a byte value x, this method returns (byte)(+1) if x >= 0 and
|
||||
* (byte)(-1) if x < 0.
|
||||
*
|
||||
* @param x the value, a byte
|
||||
* @return (byte)(+1) or (byte)(-1), depending on the sign of x
|
||||
*/
|
||||
public static byte indicator(final byte x) {
|
||||
return (x >= ZB) ? PB : NB;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a double precision value x, this method returns +1.0 if x >= 0 and
|
||||
* -1.0 if x < 0. Returns {@code NaN} if {@code x} is
|
||||
* {@code NaN}.
|
||||
*
|
||||
* @param x the value, a double
|
||||
* @return +1.0 or -1.0, depending on the sign of x
|
||||
*/
|
||||
public static double indicator(final double x) {
|
||||
if (Double.isNaN(x)) {
|
||||
return Double.NaN;
|
||||
}
|
||||
return (x >= 0.0) ? 1.0 : -1.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a float value x, this method returns +1.0F if x >= 0 and -1.0F if x <
|
||||
* 0. Returns {@code NaN} if {@code x} is {@code NaN}.
|
||||
*
|
||||
* @param x the value, a float
|
||||
* @return +1.0F or -1.0F, depending on the sign of x
|
||||
*/
|
||||
public static float indicator(final float x) {
|
||||
if (Float.isNaN(x)) {
|
||||
return Float.NaN;
|
||||
}
|
||||
return (x >= 0.0F) ? 1.0F : -1.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* For an int value x, this method returns +1 if x >= 0 and -1 if x < 0.
|
||||
*
|
||||
* @param x the value, an int
|
||||
* @return +1 or -1, depending on the sign of x
|
||||
*/
|
||||
public static int indicator(final int x) {
|
||||
return (x >= 0) ? 1 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a long value x, this method returns +1L if x >= 0 and -1L if x < 0.
|
||||
*
|
||||
* @param x the value, a long
|
||||
* @return +1L or -1L, depending on the sign of x
|
||||
*/
|
||||
public static long indicator(final long x) {
|
||||
return (x >= 0L) ? 1L : -1L;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a short value x, this method returns (short)(+1) if x >= 0 and
|
||||
* (short)(-1) if x < 0.
|
||||
*
|
||||
* @param x the value, a short
|
||||
* @return (short)(+1) or (short)(-1), depending on the sign of x
|
||||
*/
|
||||
public static short indicator(final short x) {
|
||||
return (x >= ZS) ? PS : NS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize an angle in a 2&pi wide interval around a center value.
|
||||
* <p>This method has three main uses:</p>
|
||||
|
@ -235,6 +164,72 @@ public final class MathUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first argument with the sign of the second argument.
|
||||
*
|
||||
* @param magnitude Magnitude of the returned value.
|
||||
* @param sign Sign of the returned value.
|
||||
* @return a value with magnitude equal to {@code magnitude} and with the
|
||||
* same sign as the {@code sign} argument.
|
||||
* @throws MathArithmeticException if {@code magnitude == Short.MIN_VALUE}
|
||||
* and {@code sign >= 0}.
|
||||
*/
|
||||
public static short copySign(short magnitude, short sign) {
|
||||
if ((magnitude >= 0 && sign >= 0) ||
|
||||
(magnitude < 0 && sign < 0)) { // Sign is OK.
|
||||
return magnitude;
|
||||
} else if (sign >= 0 &&
|
||||
magnitude == Short.MIN_VALUE) {
|
||||
throw new MathArithmeticException(LocalizedFormats.OVERFLOW);
|
||||
} else {
|
||||
return (short) -magnitude; // Flip sign.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first argument with the sign of the second argument.
|
||||
*
|
||||
* @param magnitude Magnitude of the returned value.
|
||||
* @param sign Sign of the returned value.
|
||||
* @return a value with magnitude equal to {@code magnitude} and with the
|
||||
* same sign as the {@code sign} argument.
|
||||
* @throws MathArithmeticException if {@code magnitude == Integer.MIN_VALUE}
|
||||
* and {@code sign >= 0}.
|
||||
*/
|
||||
public static int copySign(int magnitude, int sign) {
|
||||
if ((magnitude >= 0 && sign >= 0) ||
|
||||
(magnitude < 0 && sign < 0)) { // Sign is OK.
|
||||
return magnitude;
|
||||
} else if (sign >= 0 &&
|
||||
magnitude == Integer.MIN_VALUE) {
|
||||
throw new MathArithmeticException(LocalizedFormats.OVERFLOW);
|
||||
} else {
|
||||
return (int) -magnitude; // Flip sign.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first argument with the sign of the second argument.
|
||||
*
|
||||
* @param magnitude Magnitude of the returned value.
|
||||
* @param sign Sign of the returned value.
|
||||
* @return a value with magnitude equal to {@code magnitude} and with the
|
||||
* same sign as the {@code sign} argument.
|
||||
* @throws MathArithmeticException if {@code magnitude == Long.MIN_VALUE}
|
||||
* and {@code sign >= 0}.
|
||||
*/
|
||||
public static long copySign(long magnitude, long sign) {
|
||||
if ((magnitude >= 0 && sign >= 0) ||
|
||||
(magnitude < 0 && sign < 0)) { // Sign is OK.
|
||||
return magnitude;
|
||||
} else if (sign >= 0 &&
|
||||
magnitude == Long.MIN_VALUE) {
|
||||
throw new MathArithmeticException(LocalizedFormats.OVERFLOW);
|
||||
} else {
|
||||
return (long) -magnitude; // Flip sign.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a>
|
||||
* for int value {@code x}.
|
||||
|
|
|
@ -1089,4 +1089,20 @@ public class FastMathTest {
|
|||
Assert.assertEquals(0, FastMath.log(0, 10), 0);
|
||||
Assert.assertEquals(Double.NEGATIVE_INFINITY, FastMath.log(10, 0), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndicatorDouble() {
|
||||
double delta = 0.0;
|
||||
Assert.assertEquals(1.0, FastMath.copySign(1d, 2.0), delta);
|
||||
Assert.assertEquals(1.0, FastMath.copySign(1d, 0.0), delta);
|
||||
Assert.assertEquals(-1.0, FastMath.copySign(1d, -2.0), delta);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndicatorFloat() {
|
||||
float delta = 0.0F;
|
||||
Assert.assertEquals(1.0F, FastMath.copySign(1d, 2.0F), delta);
|
||||
Assert.assertEquals(1.0F, FastMath.copySign(1d, 0.0F), delta);
|
||||
Assert.assertEquals(-1.0F, FastMath.copySign(1d, -2.0F), delta);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,47 +102,30 @@ public final class MathUtilsTest {
|
|||
|
||||
@Test
|
||||
public void testIndicatorByte() {
|
||||
Assert.assertEquals((byte)1, MathUtils.indicator((byte)2));
|
||||
Assert.assertEquals((byte)1, MathUtils.indicator((byte)0));
|
||||
Assert.assertEquals((byte)(-1), MathUtils.indicator((byte)(-2)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndicatorDouble() {
|
||||
double delta = 0.0;
|
||||
Assert.assertEquals(1.0, MathUtils.indicator(2.0), delta);
|
||||
Assert.assertEquals(1.0, MathUtils.indicator(0.0), delta);
|
||||
Assert.assertEquals(-1.0, MathUtils.indicator(-2.0), delta);
|
||||
Assert.assertTrue(Double.isNaN(MathUtils.indicator(Double.NaN)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndicatorFloat() {
|
||||
float delta = 0.0F;
|
||||
Assert.assertEquals(1.0F, MathUtils.indicator(2.0F), delta);
|
||||
Assert.assertEquals(1.0F, MathUtils.indicator(0.0F), delta);
|
||||
Assert.assertEquals(-1.0F, MathUtils.indicator(-2.0F), delta);
|
||||
Assert.assertEquals((byte)1, MathUtils.copySign((byte)1, (byte)2));
|
||||
Assert.assertEquals((byte)1, MathUtils.copySign((byte)1, (byte)0));
|
||||
Assert.assertEquals((byte)(-1), MathUtils.copySign((byte)1, (byte)(-2)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndicatorInt() {
|
||||
Assert.assertEquals(1, MathUtils.indicator((2)));
|
||||
Assert.assertEquals(1, MathUtils.indicator((0)));
|
||||
Assert.assertEquals((-1), MathUtils.indicator((-2)));
|
||||
Assert.assertEquals(1, MathUtils.copySign(1, 2));
|
||||
Assert.assertEquals(1, MathUtils.copySign(1, 0));
|
||||
Assert.assertEquals((-1), MathUtils.copySign(1, -2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndicatorLong() {
|
||||
Assert.assertEquals(1L, MathUtils.indicator(2L));
|
||||
Assert.assertEquals(1L, MathUtils.indicator(0L));
|
||||
Assert.assertEquals(-1L, MathUtils.indicator(-2L));
|
||||
Assert.assertEquals(1L, MathUtils.copySign(1L, 2L));
|
||||
Assert.assertEquals(1L, MathUtils.copySign(1L, 0L));
|
||||
Assert.assertEquals(-1L, MathUtils.copySign(1L, -2L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndicatorShort() {
|
||||
Assert.assertEquals((short)1, MathUtils.indicator((short)2));
|
||||
Assert.assertEquals((short)1, MathUtils.indicator((short)0));
|
||||
Assert.assertEquals((short)(-1), MathUtils.indicator((short)(-2)));
|
||||
Assert.assertEquals((short)1, MathUtils.copySign((short)1, (short)2));
|
||||
Assert.assertEquals((short)1, MathUtils.copySign((short)1, (short)0));
|
||||
Assert.assertEquals((short)(-1), MathUtils.copySign((short)1, (short)(-2)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue