[R] a very simple question

(Ted Harding) Ted.Harding at wlandres.net
Mon Mar 19 16:02:28 CET 2012

On 19-Mar-2012 Dajiang Liu wrote:
> Thanks a lot for the clarification. I just find it very bizarre
> that if you run
> a=0.1*(1:9);which(a==0.4) 
> it returns the right answer. Anyway, I will pay attention next time.
> Thanks a > lot.

The basic explanation is that, for an integer r (0<r<10), what is
stored in binary representation by R for 0.1*r or for "0.r" or
for r/10 is always an approximation to the exact value (with the
possible exception of r=5).

The exact detail of the binary representation may depend on how
it was obtained, by any of several different methods of calculation
which, mathematically, are exactly equivalent but, in the binary
representations stored in the computer, may be slightly different.


  0.1*(1:9) - (1:9)/10
  # [1] 0.000000e+00 0.000000e+00 5.551115e-17 0.000000e+00
  # [5] 0.000000e+00 1.110223e-16 1.110223e-16 0.000000e+00
  # [8] 0.000000e+00

  0.1*(1:9) - c(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9)
  # [1] 0.000000e+00 0.000000e+00 5.551115e-17 0.000000e+00
  # [5] 0.000000e+00 1.110223e-16 1.110223e-16 0.000000e+00
  # [8] 0.000000e+00

  # (1:9)/10 - c(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9)
  # [1] 0 0 0 0 0 0 0 0 0

  cumsum(rep(0.3,9))/3 - (1:9)/10
  # [1] -1.387779e-17 -2.775558e-17  0.000000e+00 -5.551115e-17
  # [5]  0.000000e+00  0.000000e+00  1.110223e-16 -1.110223e-16
  # [9] -1.110223e-16

and so on ...

The third example suggests that when R is given a decimal
fraction "0.r" it recognises that this is equivalent to r/10
and calculates it accordingly, hence the agreement between
(1:9)/10 and c(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9). (I would
need to check the source code to verify that statement, however).

The short answer (as has been pointed out) is that you cannot
count on exact agreement, within R (or most other numerical
software), between a value calculated by one numerical method
and the value calculated by another numerical method which is
mathematically equivalent.

Some numerical software will work by storing the expression
given to it not as a number but as a sequence of operations
performed on given digits, only evaluating this at the last
moment along with other similar expressions, working within
the scale (e.g. decimal scale for numbers given like "123.456")
thus obtaining maximum accuracy within the allocated storage.
An example it the arbitrary-precision calculator 'bc'.

Many (most?) hand-held digital calculators work to an internal
decimal representation such as BCD ("binary-coded decimal")
where each byte is split into two half-bytes of 4 binary
digits, each capable of storing a number from 0 to 9; then
they can perform exact decimal arithmetic (to within the
precision of storage) for decimal numbers, avoiding the
imprecision resulting from conversion to binary (but may
exhibit similar problems to the above for binary input).


E-Mail: (Ted Harding) <Ted.Harding at wlandres.net>
Date: 19-Mar-2012  Time: 15:02:03
This message was sent by XFMail

More information about the R-help mailing list