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. 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") }
On Mon, Sep 03, 2007 at 08:59:22AM +0200, 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.A rational number has a finite binary expansion iff its denominator is a power of 2. Numbers 0.1 and 0.2 are 1/10 and 1/5, so they have 5 in their denominator. Their binary expansion is 0.1 = .0001100110011001100110011001100110... 0.2 = .0011001100110011001100110011001100... A double variable stores the numbers rounded to 53 significant binary digits. Hence, they are not exactly 0.1 and 0.2, as may be seen in formatC(0.1,digits=30) # [1] "0.100000000000000005551115123126" formatC(0.2,digits=30) # [1] "0.200000000000000011102230246252" In order to compare numbers with some tolerance, the function all.equal may be used, which you also mention below. See its help page, which specifies the tolerance to be .Machine$double.eps ^ 0.5.> 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.Not C compiler, but the hardware. Petr Savicky.> 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 >
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
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 >