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")
}
When 1+2 != 3 (PR#9895)
7 messages · marco.vicentini at gmail.com, Petr Savicky, Duncan Murdoch +3 more
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
On 03-Sep-07 15:12:06, Henrik Bengtsson wrote:
On 9/2/07, marco.vicentini at gmail.com <marco.vicentini at gmail.com> wrote:
[...] 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
Well, if you guys want a Quiz: ... My favourite example
of something which will probably never work on R (or any
machine which implements fixed-length binary real arithmetic).
An interated function scheme on [0,1] is defined by
if 0 <= x <= 0.5 then next x = 2*x
if 0.5 < x <= 1 then next x = 2*(1 - x)
in R:
nextX <- function(x){ifelse(x<=0.5, 2*x, 2*(1-x))}
and try, e.g.,
x<-3/7; for(i in (1:60)){x<-nextX(x); print(c(i,x))}
x = 0 is an absorbing state.
x = 1 -> x = 0
x = 1/2 -> 1 -> 0
...
(these work in R)
If K is an odd integer, and 0 < r < K, then
x = r/K -> ... leads into a periodic set.
E.g. (see above) 3/7 -> 6/7 -> 2/7 -> 4/7 -> 2/7
All other numbers x outside these sets generate non-periodic
sequences.
Apart from the case where initial x = 1/2^k, none of the
above is true in R (e.g. the example above).
So can you devise an "isEqual" function which will make this
work?
It's only Monday .. plenty of time!
Best wishes,
Ted.
--------------------------------------------------------------------
E-Mail: (Ted Harding) <Ted.Harding at manchester.ac.uk>
Fax-to-email: +44 (0)870 094 0861
Date: 03-Sep-07 Time: 17:32:38
------------------------------ XFMail ------------------------------
--------------------------------------------------------------------
E-Mail: (Ted Harding) <ted.harding at nessie.mcc.ac.uk>
Fax-to-email: +44 (0)870 094 0861
Date: 03-Sep-07 Time: 18:50:23
------------------------------ XFMail ------------------------------
Not sure if this counts but using the Ryacas package
library(Ryacas)
x <- Sym("x")
Set(x, Sym(3)/7)
expression(3/7)
cat(i, "0: "); print(x)
10 0: expression(3/7)
for(i in 1:10) {
+ yacas("Set(x, If(x <= 1/2, 2*x, 2*(1-x)))")
+ cat(i, "i: "); print(x)
+ }
1 i: expression(6/7)
2 i: expression(2/7)
3 i: expression(4/7)
4 i: expression(6/7)
5 i: expression(2/7)
6 i: expression(4/7)
7 i: expression(6/7)
8 i: expression(2/7)
9 i: expression(4/7)
10 i: expression(6/7)
On 9/3/07, Ted Harding <ted.harding at nessie.mcc.ac.uk> wrote:
On 03-Sep-07 15:12:06, Henrik Bengtsson wrote:
On 9/2/07, marco.vicentini at gmail.com <marco.vicentini at gmail.com> wrote:
[...] 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
Well, if you guys want a Quiz: ... My favourite example
of something which will probably never work on R (or any
machine which implements fixed-length binary real arithmetic).
An interated function scheme on [0,1] is defined by
if 0 <= x <= 0.5 then next x = 2*x
if 0.5 < x <= 1 then next x = 2*(1 - x)
in R:
nextX <- function(x){ifelse(x<=0.5, 2*x, 2*(1-x))}
and try, e.g.,
x<-3/7; for(i in (1:60)){x<-nextX(x); print(c(i,x))}
x = 0 is an absorbing state.
x = 1 -> x = 0
x = 1/2 -> 1 -> 0
...
(these work in R)
If K is an odd integer, and 0 < r < K, then
x = r/K -> ... leads into a periodic set.
E.g. (see above) 3/7 -> 6/7 -> 2/7 -> 4/7 -> 2/7
All other numbers x outside these sets generate non-periodic
sequences.
Apart from the case where initial x = 1/2^k, none of the
above is true in R (e.g. the example above).
So can you devise an "isEqual" function which will make this
work?
It's only Monday .. plenty of time!
Best wishes,
Ted.
--------------------------------------------------------------------
E-Mail: (Ted Harding) <Ted.Harding at manchester.ac.uk>
Fax-to-email: +44 (0)870 094 0861
Date: 03-Sep-07 Time: 17:32:38
------------------------------ XFMail ------------------------------
--------------------------------------------------------------------
E-Mail: (Ted Harding) <ted.harding at nessie.mcc.ac.uk>
Fax-to-email: +44 (0)870 094 0861
Date: 03-Sep-07 Time: 18:50:23
------------------------------ XFMail ------------------------------
______________________________________________ R-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
On 03-Sep-07 19:25:58, Gabor Grothendieck wrote:
Not sure if this counts but using the Ryacas package
Gabor, I'm afraid it doesn't count! (Though I didn't
exclude it explicitly). I'm not interested in the behaviour
of the sequence with denominator = 7 particularly.
The system is in fact an example of simulating chaotic
systems on a computer.
For instance, one of the classic illustrations is
next x = 2*x*(1-x)
for any real x. The question is, how does a finite-length
binary representation behave?
Petr Savicky [privately] sent me a similar example:
Starting with r/K:
nextr <- function(r){ifelse(r<=K/2, 2*r, 2*(K-r))}
"For K = 7 and r = 3, this yields r = 3, 6, 2, 4, 6, ...
Dividing this by K=7, one gets the correct period with
approximately correct numbers."
Best wishes,
Ted.
--------------------------------------------------------------------
E-Mail: (Ted Harding) <Ted.Harding at manchester.ac.uk>
Fax-to-email: +44 (0)870 094 0861
Date: 03-Sep-07 Time: 21:02:27
------------------------------ XFMail ------------------------------