6506405: Math.abs(float) is slow

Reviewed-by: darcy
This commit is contained in:
Brian Burkhalter 2021-07-14 15:50:51 +00:00
parent 357fe09f2e
commit c0d4efff3c
4 changed files with 129 additions and 8 deletions

View file

@ -1527,7 +1527,8 @@ public final class Math {
*/
@IntrinsicCandidate
public static float abs(float a) {
return (a <= 0.0F) ? 0.0F - a : a;
// Convert to bit field form, zero the sign bit, and convert back
return Float.intBitsToFloat(Float.floatToRawIntBits(a) & FloatConsts.MAG_BIT_MASK);
}
/**
@ -1552,7 +1553,9 @@ public final class Math {
*/
@IntrinsicCandidate
public static double abs(double a) {
return (a <= 0.0D) ? 0.0D - a : a;
// Convert to bit field form, zero the sign bit, and convert back
return Double.longBitsToDouble(Double.doubleToRawLongBits(a) & DoubleConsts.MAG_BIT_MASK);
}
/**

View file

@ -73,12 +73,20 @@ public class DoubleConsts {
*/
public static final long SIGNIF_BIT_MASK = 0x000FFFFFFFFFFFFFL;
/**
* Bit mask to isolate the magnitude bits (combined exponent and
* significand fields) of a {@code double}.
*/
public static final long MAG_BIT_MASK = ~SIGN_BIT_MASK;
static {
// verify bit masks cover all bit positions and that the bit
// masks are non-overlapping
assert(((SIGN_BIT_MASK | EXP_BIT_MASK | SIGNIF_BIT_MASK) == ~0L) &&
(((SIGN_BIT_MASK & EXP_BIT_MASK) == 0L) &&
((SIGN_BIT_MASK & SIGNIF_BIT_MASK) == 0L) &&
((EXP_BIT_MASK & SIGNIF_BIT_MASK) == 0L)));
((EXP_BIT_MASK & SIGNIF_BIT_MASK) == 0L)) &&
((SIGN_BIT_MASK | MAG_BIT_MASK) == ~0L));
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -73,12 +73,19 @@ public class FloatConsts {
*/
public static final int SIGNIF_BIT_MASK = 0x007FFFFF;
/**
* Bit mask to isolate the magnitude bits (combined exponent and
* significand fields) of a {@code float}.
*/
public static final int MAG_BIT_MASK = ~SIGN_BIT_MASK;
static {
// verify bit masks cover all bit positions and that the bit
// masks are non-overlapping
assert(((SIGN_BIT_MASK | EXP_BIT_MASK | SIGNIF_BIT_MASK) == ~0) &&
(((SIGN_BIT_MASK & EXP_BIT_MASK) == 0) &&
((SIGN_BIT_MASK & SIGNIF_BIT_MASK) == 0) &&
((EXP_BIT_MASK & SIGNIF_BIT_MASK) == 0)));
((EXP_BIT_MASK & SIGNIF_BIT_MASK) == 0)) &&
((SIGN_BIT_MASK | MAG_BIT_MASK) == ~0));
}
}