The value of floatToRawIntBits(0.0f/0.0f) is different on x86_64 and aarch64?

Aleksey Shipilev shade at redhat.com
Mon Jul 15 07:10:22 UTC 2019


On 7/15/19 8:46 AM, Aleksey Shipilev wrote:
> On 7/15/19 6:05 AM, Tianhua huang wrote:
>> The value of floatToRawIntBits(0.0f/0.0f) is different on x86_64 and
>> aarch64? Does it depends on the platform? I think the behaviour should be
>> same on different platforms, right?
> 
> Why should it be? 0.0f/0.0f is NaN. There are multiple allowed representations of NaN in IEEE-754.
> And there is a difference about "raw" conversions:
> 
> "If the argument is NaN, the result is the integer representing the actual NaN value. Unlike the
> floatToIntBits method, floatToRawIntBits does not collapse all the bit patterns encoding a NaN to a
> single "canonical" NaN value."
>  (https://docs.oracle.com/javase/8/docs/api/java/lang/Float.html#floatToRawIntBits-float-)
> 
> 
> $ cat Test.scala
> import java.lang.Float.floatToRawIntBits;
> import java.lang.Float.floatToIntBits;
> import java.lang.Float.intBitsToFloat;
> import java.lang.Float.isNaN;
> 
> object Test {
>    def main(args : Array[String]) {
>       var f = 0.0f/0.0f;
>       System.out.println(f);
>       System.out.println(isNaN(f));
>       System.out.println(floatToRawIntBits(f));
>       System.out.println(intBitsToFloat(floatToRawIntBits(f)));
>       System.out.println(floatToIntBits(f));
>       System.out.println(intBitsToFloat(floatToIntBits(f)));
>    }
> }
> 
> 
> $ scalac Test.scala
> $ java Test
> NaN
> true
> -4194304
> NaN
> 2143289344
> NaN

Somewhat amusingly, the same test in plain Java yields:

$ cat Test.java
public class Test {
   public static void main(String... args) {
      float f = 0.0f/0.0f;
      System.out.println(f);
      System.out.println(Float.isNaN(f));
      System.out.println(Float.floatToRawIntBits(f));
      System.out.println(Float.intBitsToFloat(Float.floatToRawIntBits(f)));
      System.out.println(Float.floatToIntBits(f));
      System.out.println(Float.intBitsToFloat(Float.floatToIntBits(f)));
   }
}

$ javac Test.java
$ java Test
NaN
true
2143289344
NaN
2143289344
NaN

...which is a bit less surprising. Both javac and scalac collapse 0.0/0.0 to constant pool NaNf. I
suspect scalac writes down the non-canonical representation for NaN into constant pool. So, if you
want to follow up on this irregularity -- which I still believe is not a bug -- I suggest talking to
Scala compiler people.

-- 
Thanks,
-Aleksey



More information about the jdk-dev mailing list