Dear R Helpers, I am trying to extract the modulus from divisions by a sequence of fractions. I noticed that %% seems to behave inconsistently (to my untutored eye), thus:> 0.1%%0.1[1] 0> 0.2%%0.1[1] 0> 0.3%%0.1[1] 0.1> 0.4%%0.1[1] 0> 0.5%%0.1[1] 0.1> 0.6%%0.1[1] 0.1> 0.7%%0.1[1] 0.1> 0.8%%0.1[1] 0> 0.9%%0.1The modulus for 0.1, 0.2, 0.4 and 0.8 is zero, as I'd expect. But, the modulus for 0.3, 0.6, 0.7 and 0.9 is 0.1 - which I did not expect. I can see no obvious rule that predicts whether x%%0.1 will give an answer of 0 or 0.1. I could find no explanation of the way that %% works in the R manuals. So, I have 3 questions:- 1) Why is the modulus of 0.3%%0.1 (and 0.5%%0.1 and 0.6%%0.1...) not zero? 2) Are there any algorithms in R that use the %% operator with fractional divisors in this way, and do they know about its apparently inconsistent behaviour? 3) If %% is not intended for use with fractional divisors, then would it be a good idea to trap attempts to use them? Thanks, in advance, for your help Jonathan Williams
"Jonathan Williams" <jonathan.williams at pharmacology.oxford.ac.uk> writes:> Dear R Helpers, > > I am trying to extract the modulus from divisions by a sequence of > fractions. > I noticed that %% seems to behave inconsistently (to my untutored eye), > thus: > > > 0.1%%0.1 > [1] 0 > > 0.2%%0.1 > [1] 0 > > 0.3%%0.1 > [1] 0.1 > > 0.4%%0.1 > [1] 0 > > 0.5%%0.1 > [1] 0.1 > > 0.6%%0.1 > [1] 0.1 > > 0.7%%0.1 > [1] 0.1 > > 0.8%%0.1 > [1] 0 > > 0.9%%0.1 > > The modulus for 0.1, 0.2, 0.4 and 0.8 is zero, as I'd expect. But, the > modulus > for 0.3, 0.6, 0.7 and 0.9 is 0.1 - which I did not expect. I can see no > obvious > rule that predicts whether x%%0.1 will give an answer of 0 or 0.1. I could > find > no explanation of the way that %% works in the R manuals. So, I have 3 > questions:- > > 1) Why is the modulus of 0.3%%0.1 (and 0.5%%0.1 and 0.6%%0.1...) not zero? > 2) Are there any algorithms in R that use the %% operator with fractional > divisors > in this way, and do they know about its apparently inconsistent behaviour? > 3) If %% is not intended for use with fractional divisors, then would it be > a > good idea to trap attempts to use them?These are not fractions but floating point numbers. See FAQ 7.31 http://cran.r-project.org/doc/FAQ/R-FAQ.html#Why-doesn_0027t-R-think-these-numbers-are-equal_003f and the references therein for reasons why 0.3 is not an integer multiple of 0.1 in binary. etc. -- O__ ---- Peter Dalgaard ?ster Farimagsgade 5, Entr.B c/ /'_ --- Dept. of Biostatistics PO Box 2099, 1014 Cph. K (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907
To answer part 1) of your question, see point 7.31 in the R FAQ (http://cran.r-project.org/doc/FAQ/R-FAQ.html#Why-doesn_0027t-R-think-these- numbers-are-equal_003f).> 0.3 - 3*0.1[1] -5.551115e-17 It always amazes me in how many different guises the problem of floating point representation crops up. HTH>-----Original Message----- >From: r-help-bounces@stat.math.ethz.ch >[mailto:r-help-bounces@stat.math.ethz.ch] On Behalf Of >Jonathan Williams >Sent: 22 November 2006 12:15 PM >To: Ethz. Ch >Subject: [R] odd behaviour of %%? > >Dear R Helpers, > >I am trying to extract the modulus from divisions by a >sequence of fractions. >I noticed that %% seems to behave inconsistently (to my untutored eye), >thus: > >> 0.1%%0.1 >[1] 0 >> 0.2%%0.1 >[1] 0 >> 0.3%%0.1 >[1] 0.1 >> 0.4%%0.1 >[1] 0 >> 0.5%%0.1 >[1] 0.1 >> 0.6%%0.1 >[1] 0.1 >> 0.7%%0.1 >[1] 0.1 >> 0.8%%0.1 >[1] 0 >> 0.9%%0.1 > >The modulus for 0.1, 0.2, 0.4 and 0.8 is zero, as I'd expect. >But, the modulus for 0.3, 0.6, 0.7 and 0.9 is 0.1 - which I >did not expect. I can see no obvious rule that predicts >whether x%%0.1 will give an answer of 0 or 0.1. I could find >no explanation of the way that %% works in the R manuals. So, I have 3 >questions:- > >1) Why is the modulus of 0.3%%0.1 (and 0.5%%0.1 and >0.6%%0.1...) not zero? >2) Are there any algorithms in R that use the %% operator with >fractional divisors in this way, and do they know about its >apparently inconsistent behaviour? >3) If %% is not intended for use with fractional divisors, >then would it be a good idea to trap attempts to use them? > >Thanks, in advance, for your help > >Jonathan Williams > >______________________________________________ >R-help@stat.math.ethz.ch mailing list >https://stat.ethz.ch/mailman/listinfo/r-help >PLEASE do read the posting guide >http://www.R-project.org/posting-guide.html >and provide commented, minimal, self-contained, reproducible code. >******************** Nedbank Limited Reg No 1951/000009/06. The following link displays the names of the Nedbank Board of Directors and Company Secretary. [ http://www.nedbank.co.za/terms/DirectorsNedbank.htm ] This email is confidential and is intended for the addressee only. The following link will take you to Nedbank's legal notice. [ http://www.nedbank.co.za/terms/EmailDisclaimer.htm ] ******************** [[alternative HTML version deleted]]
On 22-Nov-06 Jonathan Williams wrote:> Dear R Helpers, > > I am trying to extract the modulus from divisions by a > sequence of fractions. > I noticed that %% seems to behave inconsistently (to my > untutored eye), thus: > >> 0.1%%0.1 > [1] 0 >> 0.2%%0.1 > [1] 0 >> 0.3%%0.1 > [1] 0.1 >> 0.4%%0.1 > [1] 0 >> 0.5%%0.1 > [1] 0.1 >> 0.6%%0.1 > [1] 0.1 >> 0.7%%0.1 > [1] 0.1 >> 0.8%%0.1 > [1] 0 >> 0.9%%0.1This is yet another manifestation of the fact that R (like most computer languages) stores numbers as binary representations of fixed length. This is OK for inetegers up to a certain maximum value, but relatively few factions (those which are multiples of powers of 1/2) will be stored exactly. In particular, 0.1 is not stored exactly. When you do 0.2 %% 0.1, you will be getting the remainder of twice the binary representation of 0.1, modulo 0.1, which will be zero; and similarly for 0.4 and 0.8, since these are going up by powers of 2 and the relationships between their binary representations will match what you would expect. However, the binary representation of 0.3 does not correspond exactly to 3 times the binary representation of 0.1: 0.3 - 3*0.1 [1] -5.551115e-17 so 3*0.1 is represented by a binary fraction slightly greater than the binary representation of 0.3, so 0.1 only "goes into" 0.3 twice, with a remainder slightly less than 0.1 which rounds to 0.1 when displayed as a result: > 0.3 %% 0.1 [1] 0.1 > 0.1 - (0.3 %% 0.1) [1] 2.775558e-17 Similarly for 0.5, 0.6, 0.7 and 0.9.> The modulus for 0.1, 0.2, 0.4 and 0.8 is zero, as I'd expect. > But, the modulus for 0.3, 0.6, 0.7 and 0.9 is 0.1 - which I > did not expect. I can see no obvious rule that predicts whether > x%%0.1 will give an answer of 0 or 0.1. I could find no > explanation of the way that %% works in the R manuals. So, > I have 3 questions:- > > 1) Why is the modulus of 0.3%%0.1 (and 0.5%%0.1 and 0.6%%0.1...) > not zero?See above.> 2) Are there any algorithms in R that use the %% operator with > fractional divisors in this way,I don't know -- though others will!> and do they know about its apparently inconsisten behaviour?People who write algorithms should be aware of such effects of binary representation, so a well-written algorithm will take account of this danger.> 3) If %% is not intended for use with fractional divisors, > then would it be a good idea to trap attempts to use them?The best protection against this kind of thing is circumspection on the part of the programmer -- who, therefore should do his own trapping. An alternative aproach to the calculations you made could be > 0.3 - 0.1*(0.3/0.1) [1] 0 which is "algebraically" equivalent, and gives the right answer: > identical(0.3 - 0.1*(0.3/0.1),0) [1] TRUE However, this is not always going to work either: > 1000001.1 - (1000001.1/0.1)*0.1 [1] -1.164153e-10 so it's prudent to wrap it in a suitable round(): > round(1000001.1 - (1000001.1/0.1)*0.1, digits=9) [1] 0 but you still have to be aware of what value to set the number of digits to round to: > round(1000001.1 - (1000001.1/0.1)*0.1, digits=10) [1] -1e-10 Hoping this helps, Ted. -------------------------------------------------------------------- E-Mail: (Ted Harding) <Ted.Harding at nessie.mcc.ac.uk> Fax-to-email: +44 (0)870 094 0861 Date: 22-Nov-06 Time: 11:33:05 ------------------------------ XFMail ------------------------------