From murdoch at stats.uwo.ca  Mon Sep  3 16:54:23 2007
From: murdoch at stats.uwo.ca (Duncan Murdoch)
Date: Mon, 03 Sep 2007 10:54:23 -0400
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: <46DC201F.8040100@stats.uwo.ca>

On 03/09/2007 2:59 AM, 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.

The FAQ 7.31 gives general help on this.  Repeating it in every instance 
where it affects computations wouldn't make sense.

Please don't report unavoidable problems as bugs.

Duncan Murdoch

> 
> 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.
> 
> 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)
Duncan Murdoch