Skip to content

Commit ed0e518

Browse files
lowasserGoogle Java Core Libraries
authored andcommitted
Add {Int,Long}Math.saturatedAbs.
RELNOTES=Add {Int,Long}Math.saturatedAbs. PiperOrigin-RevId: 755417595
1 parent 41c7d2d commit ed0e518

File tree

8 files changed

+162
-0
lines changed

8 files changed

+162
-0
lines changed

android/guava-tests/test/com/google/common/math/IntMathTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,17 @@ public void testIsPrime() {
692692
}
693693
}
694694

695+
public void testSaturatedAbs() {
696+
assertEquals(Integer.MAX_VALUE, IntMath.saturatedAbs(Integer.MIN_VALUE));
697+
assertEquals(Integer.MAX_VALUE, IntMath.saturatedAbs(Integer.MAX_VALUE));
698+
assertEquals(Integer.MAX_VALUE, IntMath.saturatedAbs(-Integer.MAX_VALUE));
699+
assertEquals(0, IntMath.saturatedAbs(0));
700+
assertEquals(1, IntMath.saturatedAbs(1));
701+
assertEquals(1, IntMath.saturatedAbs(-1));
702+
assertEquals(10, IntMath.saturatedAbs(10));
703+
assertEquals(10, IntMath.saturatedAbs(-10));
704+
}
705+
695706
private static int force32(int value) {
696707
// GWT doesn't consistently overflow values to make them 32-bit, so we need to force it.
697708
return value & 0xffffffff;

android/guava-tests/test/com/google/common/math/LongMathTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,17 @@ public void testRoundToDoubleAgainstBigIntegerUnnecessary() {
923923
}
924924
}
925925

926+
public void testSaturatedAbs() {
927+
assertEquals(Long.MAX_VALUE, LongMath.saturatedAbs(Long.MIN_VALUE));
928+
assertEquals(Long.MAX_VALUE, LongMath.saturatedAbs(Long.MAX_VALUE));
929+
assertEquals(Long.MAX_VALUE, LongMath.saturatedAbs(-Long.MAX_VALUE));
930+
assertEquals(0, LongMath.saturatedAbs(0));
931+
assertEquals(1, LongMath.saturatedAbs(1));
932+
assertEquals(1, LongMath.saturatedAbs(-1));
933+
assertEquals(10, LongMath.saturatedAbs(10));
934+
assertEquals(10, LongMath.saturatedAbs(-10));
935+
}
936+
926937
private static void failFormat(String template, Object... args) {
927938
assertWithMessage(template, args).fail();
928939
}

android/guava/src/com/google/common/math/IntMath.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,5 +717,35 @@ public static boolean isPrime(int n) {
717717
return LongMath.isPrime(n);
718718
}
719719

720+
/**
721+
* Returns the closest representable {@code int} to the absolute value of {@code x}.
722+
*
723+
* <p>This is the same thing as the true absolute value of {@code x} except in the case when
724+
* {@code x} is {@link Integer#MIN_VALUE}, in which case this returns {@link Integer#MAX_VALUE}.
725+
* (Note that {@code Integer.MAX_VALUE} is mathematically equal to {@code -Integer.MIN_VALUE -
726+
* 1}.)
727+
*
728+
* <p>There are three common APIs for determining the absolute value of an integer, all of which
729+
* behave identically except when passed {@code Integer.MIN_VALUE}. Those methods are:
730+
*
731+
* <ul>
732+
* <li>{@link Math#abs(int)}, which returns {@code Integer.MIN_VALUE} when passed {@code
733+
* Integer.MIN_VALUE}
734+
* <li>{@link Math#absExact(int)}, which throws {@link ArithmeticException} when passed {@code
735+
* Integer.MIN_VALUE}
736+
* <li>this method, {@code IntMath.saturatedAbs(int)}, which returns {@code Integer.MAX_VALUE}
737+
* when passed {@code Integer.MIN_VALUE}
738+
* </ul>
739+
*
740+
* <p>Note that if your only goal is to turn a well-distributed `int` (such as a random number or
741+
* hash code) into a well-distributed nonnegative number, the most even distribution is achieved
742+
* not by this method or other absolute value methods, but by {@code x & Integer.MAX_VALUE}.
743+
*
744+
* @since NEXT
745+
*/
746+
public static int saturatedAbs(int x) {
747+
return (x == Integer.MIN_VALUE) ? Integer.MAX_VALUE : Math.abs(x);
748+
}
749+
720750
private IntMath() {}
721751
}

android/guava/src/com/google/common/math/LongMath.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,5 +1345,34 @@ public static double roundToDouble(long x, RoundingMode mode) {
13451345
throw new AssertionError("impossible");
13461346
}
13471347

1348+
/**
1349+
* Returns the closest representable {@code long} to the absolute value of {@code x}.
1350+
*
1351+
* <p>This is the same thing as the true absolute value of {@code x} except in the case when
1352+
* {@code x} is {@link Long#MIN_VALUE}, in which case this returns {@link Long#MAX_VALUE}. (Note
1353+
* that {@code Long.MAX_VALUE} is mathematically equal to {@code -Long.MIN_VALUE - 1}.)
1354+
*
1355+
* <p>There are three common APIs for determining the absolute value of a long, all of which
1356+
* behave identically except when passed {@code Long.MIN_VALUE}. Those methods are:
1357+
*
1358+
* <ul>
1359+
* <li>{@link Math#abs(long)}, which returns {@code Long.MIN_VALUE} when passed {@code
1360+
* Long.MIN_VALUE}
1361+
* <li>{@link Math#absExact(long)}, which throws {@link ArithmeticException} when passed {@code
1362+
* Long.MIN_VALUE}
1363+
* <li>this method, {@code LongMath.saturatedAbs(long)}, which returns {@code Long.MAX_VALUE}
1364+
* when passed {@code Long.MIN_VALUE}
1365+
* </ul>
1366+
*
1367+
* <p>Note that if your only goal is to turn a well-distributed `long` (such as a random number)
1368+
* into a well-distributed nonnegative number, the most even distribution is achieved not by this
1369+
* method or other absolute value methods, but by {@code x & Long.MAX_VALUE}.
1370+
*
1371+
* @since NEXT
1372+
*/
1373+
public static long saturatedAbs(long x) {
1374+
return (x == Long.MIN_VALUE) ? Long.MAX_VALUE : Math.abs(x);
1375+
}
1376+
13481377
private LongMath() {}
13491378
}

guava-tests/test/com/google/common/math/IntMathTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,17 @@ public void testIsPrime() {
692692
}
693693
}
694694

695+
public void testSaturatedAbs() {
696+
assertEquals(Integer.MAX_VALUE, IntMath.saturatedAbs(Integer.MIN_VALUE));
697+
assertEquals(Integer.MAX_VALUE, IntMath.saturatedAbs(Integer.MAX_VALUE));
698+
assertEquals(Integer.MAX_VALUE, IntMath.saturatedAbs(-Integer.MAX_VALUE));
699+
assertEquals(0, IntMath.saturatedAbs(0));
700+
assertEquals(1, IntMath.saturatedAbs(1));
701+
assertEquals(1, IntMath.saturatedAbs(-1));
702+
assertEquals(10, IntMath.saturatedAbs(10));
703+
assertEquals(10, IntMath.saturatedAbs(-10));
704+
}
705+
695706
private static int force32(int value) {
696707
// GWT doesn't consistently overflow values to make them 32-bit, so we need to force it.
697708
return value & 0xffffffff;

guava-tests/test/com/google/common/math/LongMathTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,17 @@ public void testRoundToDoubleAgainstBigIntegerUnnecessary() {
923923
}
924924
}
925925

926+
public void testSaturatedAbs() {
927+
assertEquals(Long.MAX_VALUE, LongMath.saturatedAbs(Long.MIN_VALUE));
928+
assertEquals(Long.MAX_VALUE, LongMath.saturatedAbs(Long.MAX_VALUE));
929+
assertEquals(Long.MAX_VALUE, LongMath.saturatedAbs(-Long.MAX_VALUE));
930+
assertEquals(0, LongMath.saturatedAbs(0));
931+
assertEquals(1, LongMath.saturatedAbs(1));
932+
assertEquals(1, LongMath.saturatedAbs(-1));
933+
assertEquals(10, LongMath.saturatedAbs(10));
934+
assertEquals(10, LongMath.saturatedAbs(-10));
935+
}
936+
926937
private static void failFormat(String template, Object... args) {
927938
assertWithMessage(template, args).fail();
928939
}

guava/src/com/google/common/math/IntMath.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,5 +717,35 @@ public static boolean isPrime(int n) {
717717
return LongMath.isPrime(n);
718718
}
719719

720+
/**
721+
* Returns the closest representable {@code int} to the absolute value of {@code x}.
722+
*
723+
* <p>This is the same thing as the true absolute value of {@code x} except in the case when
724+
* {@code x} is {@link Integer#MIN_VALUE}, in which case this returns {@link Integer#MAX_VALUE}.
725+
* (Note that {@code Integer.MAX_VALUE} is mathematically equal to {@code -Integer.MIN_VALUE -
726+
* 1}.)
727+
*
728+
* <p>There are three common APIs for determining the absolute value of an integer, all of which
729+
* behave identically except when passed {@code Integer.MIN_VALUE}. Those methods are:
730+
*
731+
* <ul>
732+
* <li>{@link Math#abs(int)}, which returns {@code Integer.MIN_VALUE} when passed {@code
733+
* Integer.MIN_VALUE}
734+
* <li>{@link Math#absExact(int)}, which throws {@link ArithmeticException} when passed {@code
735+
* Integer.MIN_VALUE}
736+
* <li>this method, {@code IntMath.saturatedAbs(int)}, which returns {@code Integer.MAX_VALUE}
737+
* when passed {@code Integer.MIN_VALUE}
738+
* </ul>
739+
*
740+
* <p>Note that if your only goal is to turn a well-distributed `int` (such as a random number or
741+
* hash code) into a well-distributed nonnegative number, the most even distribution is achieved
742+
* not by this method or other absolute value methods, but by {@code x & Integer.MAX_VALUE}.
743+
*
744+
* @since NEXT
745+
*/
746+
public static int saturatedAbs(int x) {
747+
return (x == Integer.MIN_VALUE) ? Integer.MAX_VALUE : Math.abs(x);
748+
}
749+
720750
private IntMath() {}
721751
}

guava/src/com/google/common/math/LongMath.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,5 +1345,34 @@ public static double roundToDouble(long x, RoundingMode mode) {
13451345
throw new AssertionError("impossible");
13461346
}
13471347

1348+
/**
1349+
* Returns the closest representable {@code long} to the absolute value of {@code x}.
1350+
*
1351+
* <p>This is the same thing as the true absolute value of {@code x} except in the case when
1352+
* {@code x} is {@link Long#MIN_VALUE}, in which case this returns {@link Long#MAX_VALUE}. (Note
1353+
* that {@code Long.MAX_VALUE} is mathematically equal to {@code -Long.MIN_VALUE - 1}.)
1354+
*
1355+
* <p>There are three common APIs for determining the absolute value of a long, all of which
1356+
* behave identically except when passed {@code Long.MIN_VALUE}. Those methods are:
1357+
*
1358+
* <ul>
1359+
* <li>{@link Math#abs(long)}, which returns {@code Long.MIN_VALUE} when passed {@code
1360+
* Long.MIN_VALUE}
1361+
* <li>{@link Math#absExact(long)}, which throws {@link ArithmeticException} when passed {@code
1362+
* Long.MIN_VALUE}
1363+
* <li>this method, {@code LongMath.saturatedAbs(long)}, which returns {@code Long.MAX_VALUE}
1364+
* when passed {@code Long.MIN_VALUE}
1365+
* </ul>
1366+
*
1367+
* <p>Note that if your only goal is to turn a well-distributed `long` (such as a random number)
1368+
* into a well-distributed nonnegative number, the most even distribution is achieved not by this
1369+
* method or other absolute value methods, but by {@code x & Long.MAX_VALUE}.
1370+
*
1371+
* @since NEXT
1372+
*/
1373+
public static long saturatedAbs(long x) {
1374+
return (x == Long.MIN_VALUE) ? Long.MAX_VALUE : Math.abs(x);
1375+
}
1376+
13481377
private LongMath() {}
13491378
}

0 commit comments

Comments
 (0)