From hb at stat.berkeley.edu  Mon Sep  3 17:12:06 2007
From: hb at stat.berkeley.edu (Henrik Bengtsson)
Date: Mon, 3 Sep 2007 08:12:06 -0700
Subject: [Rd] When 1+2 != 3 (PR#9895)
In-Reply-To: <20070903065922.DA71966911@slim.kubism.ku.dk>
References: <20070903065922.DA71966911@slim.kubism.ku.dk>
Message-ID: <59d7961d0709030812p6b490c63j1b13f4246c1e7639@mail.gmail.com>

On 9/2/07, marco.vicentini at gmail.com <marco.vicentini at gmail.com> wrote:
> Full_Name: Marco Vicentini, University of Verona
> Version: 2.4.1 & 2.5.1
> OS: OsX & WinXP
> Submission from: (NULL) (157.27.253.46)
>
>
> When I proceed to test the following equation 1 + 2 == 3, I obviously obtain the
> value TRUE. But when I tryed to do the same using real number (i.e. 0.1 + 0.2 ==
> 0.3)  I obtained an unusual FALSE.
> In the online help there are some tricks for this problem. It suggests to use
> identical(...) which again answer FALSE. Only using isTRUE(all.equal(0.3, 0.1 +
> 0.2)) I can obtain the true value TRUE.
>
> But the problem does not concern only the operator ==. Many other functions,
> among over:  sort, order, unique, duplicate, identical are not able to deal with
> this problem. This is very dangerous because no advice are provide by the online
> help, and anybody can use these functions no think to unusual results.
>
> I think that the problem is due to how double number are store by the C
> compiler.
>
> If it may be usefull, I have written to small function (Unique and isEqual)
> which can deal with this problem of the double numbers.

Quiz: What about utility functions equalsE() and equalsPi()?
...together with examples illustrating when they return TRUE and when
they return FALSE.

Cheers

/Henrik

>
> I also add some other conditions for the same problem.
>
>         0.3 == 0.15 + 0.15
>     0.3 == 0.1 + 0.2
> 1 - 0.7 == 0.3
>     0.1 == 1 - 0.9
>
>     0.2 == 1 - 0.2 - 0.2 - 0.2 - 0.2
>    -0.2 == 1 - 0.2 - 0.2 - 0.2 - 0.2 - 0.2 - 0.2
>
> identical (0.3, 0.1 + 0.2)
> all.equal (0.3, 0.1 + 0.2)
>
> identical (-0.2 , 1 - 0.2 - 0.2 - 0.2 - 0.2 - 0.2 - 0.2)
> all.equal (-0.2 , 1 - 0.2 - 0.2 - 0.2 - 0.2 - 0.2 - 0.2)
>
> isTRUE( all.equal (-0.2 , 1 - 0.2 - 0.2 - 0.2 - 0.2 - 0.2 - 0.2) )
>
>
>    -0.2 == 1 - 0.2 - 0.2 - 0.2 - 0.2 - 0.2 - 0.2
>
> a= -0.2
> b=         1 - 0.2 - 0.2 - 0.2 - 0.2 - 0.2 - 0.2
>
> x<-c(a,b)
> sprintf("%.15f",x)
> sprintf("%.50f",x)
>
>
>
> Unique <- function(x, digits = 8, fast = TRUE) {
>
>         if (fast) {
>                 unique (round(x * 10^digits)) / 10^digits
>         } else {
>                 x = sort(x)
>                 for (i in 1:(length(x)-1))
>                         if (isTRUE(all.equal(x[i],x[i+1]))) x[i] = NaN
>                 x [ which (!is.nan(x)) ]
>         }}
>
> isEqual <- function (object, x, tol = 1e-9) {
>         if (!is.vector(object)) stop("Object must be a vector")
>         if (is.character(object)) stop("Object can not be a character")
>         if (!is.real(x)) stop("x must be a real number")
>         if (any(is.na(c(object,x)))) stop("NA is not supported")
>         if (length(x) != 1) stop("length x must equal to 1")
>
>         ifelse (abs(object - x) < tol, TRUE,FALSE)
> #       .Call("isEqual",as.real(object),as.real(x),as.real(tol), PACKAGE="mvUtils")
> }
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>



[Rd] When 1+2 != 3 (PR#9895)
Henrik Bengtsson