[R] floor()

(Ted Harding) Ted.Harding at nessie.mcc.ac.uk
Wed Nov 30 01:09:47 CET 2005


On 29-Nov-05 Werner Bier wrote:
> Dear All,
>    
>   Is this right? 
>    
>   >  floor((5.05-floor(5))*100)
> [1] 4
> 
>   I would expect 5, or am I wrong?
>    
>   Thanks and regards,
>   W

It may seem reasonable to expect it, but in the case of R
(and most other computer languages) you would be wrong.

The reason:

  print((5.05-floor(5))*100,digits=20)
  [1] 4.9999999999999822

whose floor() is 4.

The underlying reason for this and all similar phenomena is
the slight imprecision of floating-point arithmetic when the
fractional part is not a multiple of 1/2^k for some k. Since
0.05 = 1/20 and 20 = 4*5, you have a factor 1/5 in there and
the imprecision will occur.

If you really *know* what you are doing in a particular context,
you can guard against it by a deliberate tiny mistake, such as

  dtm <- 1e-13
  floor((5.05-floor(5))*100 + dtm)
  [1] 5

but you have to be careful that you don't let this happen when
it should not happen. And you have to choose your dtm with
care: 1e-14 is not good enough!

Though, since the trouble really arises at the (5.05-floor(5))
level, you could use, more judiciously,

  dtm <- 1e-15
  floor((5.05-floor(5)+dtm)*100)
  [1] 5

and here 1e-16 won't work.

Check:

  print((5.05-floor(5)),digits=20)
  [1] 0.049999999999999822

where the last "9" is the 15th digit after the ".".

Best wishes,
Ted.


--------------------------------------------------------------------
E-Mail: (Ted Harding) <Ted.Harding at nessie.mcc.ac.uk>
Fax-to-email: +44 (0)870 094 0861
Date: 30-Nov-05                                       Time: 00:09:44
------------------------------ XFMail ------------------------------




More information about the R-help mailing list