[Rd] Friday question: negative zero

Petr Savicky savicky at cs.cas.cz
Sun Sep 2 07:29:13 CEST 2007


On Sat, Sep 01, 2007 at 05:22:26PM -0600, Tony Plate wrote:
> One place where I've been caught by -ve zeros is with unit tests.  If 
> identical(-0, 0) returns FALSE, and the object storage doesn't preserve 
> -ve zeros, that can lead to test failures that are tricky to debug.
> 
> However, it doesn't look like that is too much a problem in the current 
> incarnation of R, at least running under Linux:
> 
> * identical(-0, 0) returns TRUE
> * save/load preserves -ve zero
> * however dump() does NOT preserve -ve zero
> 
> The fact that identical(-0,0) is TRUE means that we have the situation 
> where it is possible that identical(x, y) != identical(f(x), f(y)).  I 
> don't know if this is a real problem anywhere.

I think, it can be a problem, but the formulation should be modified,
since identical(x, y) != identical(f(x), f(y)) may occur even if
everything is OK. For example,
  identical(1, -1) != identical(abs(1), abs(-1)).

The problem is that it is possible to have
  identical(x, y) & ! identical(f(x), f(y))

However, this it is not a problem of R. This is a problem of IEEE 754
specification, which implies that
    x == y & f(x) != f(y)
is possible.

>  > x <- 0
>  > y <- -0
>  > 1/x
> [1] Inf
>  > 1/y
> [1] -Inf
>  > identical(x, y)
> [1] TRUE
>  > ### there exists f,x,y such that identical(x, y) != identical(f(x), f(y))
>  > identical(1/x, 1/y)
> [1] FALSE
>  > ### save/load preserves -ve zero
>  > save("y", file="y.rda")
>  > remove("y")
>  > load("y.rda")
>  > 1/y
> [1] -Inf
>  > identical(x, y)
> [1] TRUE
>  > ### dump does not preserve -ve zero
>  > dump("y", file="y.R")
>  > remove("y")
>  > source("y.R")
>  > y
> [1] 0
>  > 1/y
> [1] Inf

It works the same in my installations. Moreover, "save" preserves
-ve zeros even with ascii=TRUE, which is more similar to dump.
This may be seen in the output, where indeed "-0" may occur as a
text. So, this is another way to detect negative zero. A simpler
version is sprintf:
  sprintf("%f",0) # [1] "0.000000"
  sprintf("%f",-0) # [1] "-0.000000"

Petr Savicky.
===



More information about the R-devel mailing list