Java 8 RFR 8010430: Math.round has surprising behavior for odd values of ulp 1
Dmitry Nadezhin
dmitry.nadezhin at gmail.com
Sat Aug 24 03:17:41 UTC 2013
Guy pointed to JLS 1 semantics. Yes, it was clearer.
Ok. I agree that java.lang.Math.round() and IEEE 754-2008
roundToIntegralTiesToAway() has different semantics.
The current API specification is a little misleading.
I tried to implement JLS 1 semantics in a bit-twiddling way:
===
public static int round(float a) {
int intBits = Float.floatToRawIntBits(a);
int biasedExp = (intBits & FloatConsts.EXP_BIT_MASK) >>
(FloatConsts.SIGNIFICAND_WIDTH - 1);
int shift = (FloatConsts.SIGNIFICAND_WIDTH - 2 +
FloatConsts.EXP_BIAS) - biasedExp;
if ((shift & -32) == 0) { // shift >= 0 && shift < 32
int r = ((intBits & FloatConsts.SIGNIF_BIT_MASK) |
(FloatConsts.SIGNIF_BIT_MASK + 1));
if (intBits < 0) r = -r;
return ((r >> shift) + 1) >> 1;
} else {
return (int) a;
}
}
===
I did't compare performance of this bit-twiddling code with performance of
current code.
I need to choose a microbenchmark tool.
Previously I used the Caliper. I see that OpenJDK suggests another tool:
http://openjdk.java.net/projects/code-tools/jmh/
Nevertheless, I send this variant now in hope that it may be useful.
On Sat, Aug 24, 2013 at 1:11 AM, Brian Burkhalter <
brian.burkhalter at oracle.com> wrote:
> This is an interesting point and roundToIntegralTiesToAway() does have an
> appealing symmetry, but I think it is a broader issue than the constrained
> case I originally posted.
>
> Whichever of the approaches obtains, it seems that if the floating point
> argument A represents a real number which is also in the space of integers
> (Z), then one would expect round(A) to equal A. I think this is what most
> programmers would expect. For what it's worth, this is what appears to be
> implemented in the C language (GCC 4.2.1).
>
> Brian
>
> On Aug 23, 2013, at 1:44 PM, Dmitry Nadezhin wrote:
>
> > I guess that the method java.lang.Math.round() should correspond to
> > roundToIntegralTiesToAway of the IEEE 754-2008. Standard says about it
> > (section 5.9):
> > ===
> > roundToIntegralTiesToAway(x) rounds x to the nearest integral value, with
> > halfway cases
> > rounding away from zero
> > ===
> >
> > So the halfway cases are n + 0.5 ( like -1.5, -0.5, +0.5, +1.5).
> > Standard says that roundToIntegralTiesToAway rounds them to
> (-2,-1,+1,+2).
>
>
More information about the core-libs-dev
mailing list