diff --git a/src/main/java/org/apache/commons/math/complex/Complex.java b/src/main/java/org/apache/commons/math/complex/Complex.java index 6c8e5438b..3822a89e6 100644 --- a/src/main/java/org/apache/commons/math/complex/Complex.java +++ b/src/main/java/org/apache/commons/math/complex/Complex.java @@ -921,7 +921,7 @@ public class Complex implements FieldElement, Serializable { * where *
* Returns {@link Complex#NaN} if either real or imaginary part of the @@ -957,7 +957,7 @@ public class Complex implements FieldElement, 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); } } diff --git a/src/main/java/org/apache/commons/math/util/MathUtils.java b/src/main/java/org/apache/commons/math/util/MathUtils.java index be10a7cb4..24117fed1 100644 --- a/src/main/java/org/apache/commons/math/util/MathUtils.java +++ b/src/main/java/org/apache/commons/math/util/MathUtils.java @@ -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. *

This method has three main uses:

@@ -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 sign * for int value {@code x}. diff --git a/src/test/java/org/apache/commons/math/util/FastMathTest.java b/src/test/java/org/apache/commons/math/util/FastMathTest.java index a088cfd29..b16f0835c 100644 --- a/src/test/java/org/apache/commons/math/util/FastMathTest.java +++ b/src/test/java/org/apache/commons/math/util/FastMathTest.java @@ -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); + } } diff --git a/src/test/java/org/apache/commons/math/util/MathUtilsTest.java b/src/test/java/org/apache/commons/math/util/MathUtilsTest.java index effe84b80..43207a182 100644 --- a/src/test/java/org/apache/commons/math/util/MathUtilsTest.java +++ b/src/test/java/org/apache/commons/math/util/MathUtilsTest.java @@ -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