#1330 Float shenanigans

DanielFath Thu 25 Nov 2010

class Foo
{
  Float a
  Float b

  new make(Float a, Float b)
  {
    this.a = a;
    this.b = b;
  }

  public static Void main(Str[] args)
  {
    t1 := Foo(-2.0f, 0.0f)
    echo(t1.a * t1.b)
    echo(-2.0f*0.0f)
  }
}

Output is:

-0.0
0.0

Which isn't a bug per se but it really makes my test cases cry (since when comparing two Complex numbers they are equal but -0.0f has different hash to 0.0f).

Any way around this?

helium Thu 25 Nov 2010

Interesting:

tmp := -2.0f
echo(tmp * 0.0f)    // -0.0f
echo(-2.0f * 0.0f)  //  0.0f

Maybe some kind of constant folding that goes wrong?

brian Fri 26 Nov 2010

Remember that Fantom sys::Float is just a double in Java, and in general all the Float methods map directly to their JVM bytecode operator. So all the weirdness that exists in Java with regard to NaN, infinity, and negative zeros are part of Fantom too.

DanielFath Fri 26 Nov 2010

Fair, enough. Is there any known way around it?

PS. In Java

public class Complex {

  Double imag;
  Double real;


  public Complex(Double real, Double imag) {
      this.imag = imag;
      this.real = real;
  }


  public static void main(String[] args) {
      System.out.println(-2.0d*0.0d);
      Complex c = new Complex(-2.0d,0.0d);
      System.out.println(c.real*c.imag);
  }
}

Output:

-0.0
-0.0

brian Fri 26 Nov 2010

Well -0f == 0f. So sounds like your only problem is hash code (which is the bitwise representation of 64-bit double). In your complex class you could just trap that case in your ctor or hash method

DanielFath Fri 26 Nov 2010

Playing with fansh some weird things came up.

fansh> z := -2.0f*0.0f
0.0
fansh> nz := -2.0f
-2.0
fansh> nz *= 0.0f
fan.fansh.Var@bb7759 ?= nz *
fan.fansh.Var@1989f84 ?= nz *
-0.0
fansh> z == nz
false
fansh> z == 0.0f
true
fansh> z == -0.0f
true
fansh> nz == -0.0f
false
fansh> nz == 0.0f
false

This seems like a bug. In Java -2.0d*0.0d is always -0.0

Login or Signup to reply.