Feature suggestion: Add static equals methods to Float and Double
Ulf Adams
ulfjack at google.com
Tue Jan 8 09:16:36 UTC 2019
Technically, another option would be to have Java standardize a meaning,
and I take it you're not mentioning that because of the performance
implications?
On Tue, Jan 8, 2019 at 2:37 AM John Rose <john.r.rose at oracle.com> wrote:
> As I think you expect, isSubstitutible(x,y) will mean that x and y are
> equivalent
> for all practical purposes. One hard question is nailing down what are
> "all practical purposes". Certainly it's unfair to flip a coin while
> evaluating
> x and y separately, and claim that a distinct outcome proves a difference.
> What about viewing the bits of x and y using the Unsafe API? That's
> unfair also, since it opens the door to implementation-dependent behavior
> which might detect a difference (an irrelevant difference) between x and y.
>
> Now, floatToRawIntBits can detect differences between NaNs which
> have different numeric codes. Are two such NaNs substitutable or not?
> The evidence in favor:
> - They become equivalent when boxed in a Float, and Float claims to
> be an all-purpose box for float values.
> - The extra information produced by floatToRawIntBits is implementation
> specific, and in particular processor dependent.
> - Joe Darcy suggested to me that some processors, like x87, may
> perturb NaN bits (turning off the "signalling" bit, for example), even
> if the float value is simply bound to a parameter. This means that
> the operand to floatToRawIntBits *might*, in compiled code, possibly
> have *some* of its bits perturbed. (Thanks, Joe, for that and similar
> hair-raising stories.)
> - The previous point implies that compiled code and interpreted code
> might, in the same JVM instance, produce different results on the
> same argument. That is quite implementation specific indeed!
>
> The evidence against:
> - The existing standard API point floatToRawIntBits is not going away.
> So the isSubstitutable API point must document that floatToRawIntBits
> has the processor-dependent ability to conjure up different bits for
> x and y. Maybe it should be called isAlmostSubstitutable??
>
> The right trade-off here, I think, is to align isSubstitutable with
> Float::equals
> and simply increase the warnings on floatToRawIntBits, that this method
> can produce platform-specific results in an unpredictable way, and that
> in particular it can produce distinct answers for otherwise substitutable
> results.
>
> I also suggested to Dr. Deprecator (Stuart Marks) that floatToRawIntBits
> might be a candidate for deprecation; he said it would be a lot of expense
> for relatively little benefit. I think at least the javadoc for
> floatToRawIntBits
> should not speak so confidently, as it does, of "preserving Not-a-Number
> (NaN) values", as if these values were something that had a stable
> semantics, as if they could somehow carry application information.
>
> More background (thanks again to Joe): The NaN bits don't have a standard
> format. Different CPUs can (and often do) disagree on which bits
> mean what, and how standard arithmetic operations consume and produce
> them. There is apparently no agreed standard NaN pattern, although
> Java favors the "all zero" bit pattern as normative. Different CPUs
> may disagree on which bits denote signaling or quiet NaNs, and when
> such bits may be queried or modified. Adding the possible distinct
> treatment of the "same" NaN value in compiled vs. interpreted code
> (as well as strictfp vs. non-strictfp code), and the use of "raw" NaN
> bits seems a very risky proposition, useful only for people writing
> processor-specific code, with great care.
>
> In hindsight, I think it would have been nice to place the "raw bits"
> API points to Unsafe or a separate module. But when those API
> points were designed (1.0), there were no such hiding places.
> And it's probably too costly to fix now. If the sweet spot is to
> acknowledge the wart, but not let it spread, then we design the
> substitutability test based on Float::equals, not floatToRawIntBits.
>
> — John
>
> On Jan 6, 2019, at 4:36 PM, Hans Boehm <hboehm at google.com> wrote:
> >
> > IIUC, isSubstitutible() is not quite what's being proposed here. The
> > proposed definition here uses floatToIntBits(), not floatToRawIntBits().
> >
> > Hans
> >
> > On Sun, Jan 6, 2019 at 3:59 PM Brian Goetz <brian.goetz at oracle.com>
> wrote:
> >
> >> Followers of Project Valhalla will see that this issue comes up when
> >> defining equality on value types. The relation you are looking for is
> >> being called "substitutible"; it asks whether there is any way to
> >> distinguish between two values. For primitives other than float/double,
> >> this coincides with `==`, and similarly for references.
> >>
> >> An `isSubstitutible()` API point will likely emerge from Valhalla.
>
>
More information about the core-libs-dev
mailing list