in reply to Negative zero from a multiplication by a zero?

Floating point on most CPUs (IEEE_754-2008) has a signed zero. A negative zero typically means underflow from the left; i.e. a number too small to represent but less than true zero. It's useful in computing.
  • Comment on Re: Negative zero from a multiplication by a zero?

Replies are listed 'Best First'.
Re^2: Negative zero from a multiplication by a zero?
by Marshall (Canon) on Jun 09, 2009 at 17:11 UTC
    This is right. The precision that you are asking for has no meaning.
    foreach (-2.0,-1.9,-1.5,-1.1,-1.0,-0.9,-0.5,-0.1,-0) { printf("string=%5s digits=%9f, float2big=%24.16e\n", $_, $_, $_); } __END__ prints: string= -2 digits=-2.000000, float2big=-2.0000000000000000e+000 string= -1.9 digits=-1.900000, float2big=-1.8999999999999999e+000 string= -1.5 digits=-1.500000, float2big=-1.5000000000000000e+000 string= -1.1 digits=-1.100000, float2big=-1.1000000000000001e+000 string= -1 digits=-1.000000, float2big=-1.0000000000000000e+000 string= -0.9 digits=-0.900000, float2big=-9.0000000000000002e-001 string= -0.5 digits=-0.500000, float2big=-5.0000000000000000e-001 string= -0.1 digits=-0.100000, float2big=-1.0000000000000001e-001 string= 0 digits= 0.000000, float2big= 0.0000000000000000e+000
    Update:Well Ooops..... Somehow there is a precision problem. Sorry I couldn't replicate it.
    foreach (-2.0,-1.9,-1.5,-1.1,-1.0,-0.9,-0.5,-0.1,-0) { printf("string=%5s digits=%9f, float2big=%24.16e\n", $_, $_*0, $_*0); } string= -2 digits= 0.000000, float2big= 0.0000000000000000e+000 string= -1.9 digits= 0.000000, float2big= 0.0000000000000000e+000 string= -1.5 digits= 0.000000, float2big= 0.0000000000000000e+000 string= -1.1 digits= 0.000000, float2big= 0.0000000000000000e+000 string= -1 digits= 0.000000, float2big= 0.0000000000000000e+000 string= -0.9 digits= 0.000000, float2big= 0.0000000000000000e+000 string= -0.5 digits= 0.000000, float2big= 0.0000000000000000e+000 string= -0.1 digits= 0.000000, float2big= 0.0000000000000000e+000 string= 0 digits= 0.000000, float2big= 0.0000000000000000e+000
      I've reproduced it on two (out of two) linux boxes, one a 64bit machine.
      $ perl -e 'for (-2.0,-1.9,-1.5,-1.1,-1.0,-0.9,-0.5,-0.1,-0) {$v = $_ * 0; printf("%5s -> %2s,%.100e\n",$_,$v,$v)}' -2 -> 0,0.00000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000e+00 -1.9 -> -0,-0.0000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000e+00 -1.5 -> -0,-0.0000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000e+00 -1.1 -> -0,-0.0000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000e+00 -1 -> 0,0.00000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000e+00 -0.9 -> -0,-0.0000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000e+00 -0.5 -> -0,-0.0000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000e+00 -0.1 -> -0,-0.0000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000e+00 0 -> 0,0.00000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000e+00 $ perl -v This is perl, v5.8.8 built for i486-linux-gnu-thread-multi ... $ uname -a Linux fmdev10 2.6.24-etchnhalf.1-686 #1 SMP Tue Dec 2 07:56:33 UTC 200 +8 i686 GNU/Linux

      (Debian build)

        I don't know what to say about this. It is weird to be sure! I have a 32 bit MS box.

        C:\TEMP>perl -v This is perl, v5.10.0 built for MSWin32-x86-multi-thread (with 5 registered patches, see perl -V for more detail)
        Update: did a uname -a
        C:\TEMP>uname -a CYGWIN_NT-5.1 cobra 1.5.25(0.156/4/2) 2008-06-12 19:34 i686 Cygwin
Re^2: Negative zero from a multiplication by a zero?
by ikegami (Patriarch) on Jun 09, 2009 at 16:53 UTC
    Yes, but why would $x * 0 result in an underflow? The question stands.
      Because multiplication is sign preserving. The 0 argument might really be something that already underflowed. That is, $x * $y where $y is the canonocal representation of zero. $y might have come from another calculation. You generally don't multiply by a literal zero, since you could just leave the code out. UNLESS you wanted the sign. So that's what you got.