3

Possible Duplicate:
Why are these numbers not equal?

Just noticed this bug in R. I'm guessing it's the way 0.6 is represented, but anyone know exactly what's going on?

According to R:

0.3 %% 0.2 = 0.1
0.4 %% 0.2 = 0
0.5 %% 0.2 = 0.1
**0.6 %% 0.2 = 0.2**
0.7 %% 0.2 = 0.1
0.8 %% 0.2 = 0

What's going on?

Community
  • 1
  • 1
mike
  • 35
  • 1
  • 1
  • 3
  • 7
    [FAQ 7.31](http://cran.r-project.org/doc/FAQ/R-FAQ.html#Why-doesn_0027t-R-think-these-numbers-are-equal_003f) – Joshua Ulrich Nov 28 '12 at 21:30
  • @JoshuaUlrich: that should really be an answer, not just a comment... +1. – Stephan Kolassa Nov 28 '12 at 21:36
  • 1
    A new tag "r-faq-7.31" looks more and more useful to me... – Stephan Kolassa Nov 28 '12 at 21:51
  • @Gsee, I wouldnt call this a duplicate. The reasoning behind it is the same, but if someone is googling the problem, they wouldnt necessarily find the other answer. – Ricardo Saporta Nov 28 '12 at 21:51
  • @RicardoSaporta, that's why we close as a duplicate. They'll find this one when they search for modulo and it will link to the main Q that it is a duplicate of. Closing and deleting are not the same thing. – GSee Nov 28 '12 at 21:52

1 Answers1

6

In addition to @joshua Ulrich's comment

from ?'%%'

%% and x %/% y can be used for non-integer y, e.g. 1 %/% 0.2, but the results are subject to representation error and so may be platform-dependent. Because the IEC 60059 representation of 0.2 is a binary fraction slightly larger than 0.2, the answer to 1 %/% 0.2 should be 4 but most platforms give 5.

also similar to why we get this

> .1 + .1 + .1 == .3
[1] FALSE

as @Ben Boker pointed out, you may want to use something like

> 3:8 %% 2 / 10
[1] 0.1 0.0 0.1 0.0 0.1 0.0
Ricardo Saporta
  • 54,400
  • 17
  • 144
  • 178
  • 1
    and (as pointed out in a now-deleted answer) the 'solution' is to use integer arithmetic if possible: `6 %% 2` instead of `0.6 %% 0.2` – Ben Bolker Nov 28 '12 at 21:51
  • Yep, ended up doing that. Thanks. – mike Dec 08 '12 at 19:11
  • this seems to work: `Mod <- function(n,m){ if( m >= n ) return(n); n.digits <- nchar(strsplit(paste(n),".",fixed=T)[[1]][2]); div <- floor(n/m); rem <- n - (div * m); return(round(rem,n.digits)) } ` – theEricStone Apr 23 '14 at 18:40