[R] Noval numbers

RICHARD M. HEIBERGER rmh at temple.edu
Mon Feb 8 03:45:28 CET 2010


The attached file gives functions to go both directions.  I have used
it in class for many years.

This is very useful when studying machine representations of numbers,
for understanding mixed-radix number systems, for example time (days, hours,
minutes, seconds) or British money (pounds, shillings, pence), and for unique
indexing of cells in designed experiments.

Rich
-------------- next part --------------
## base
## Richard M. Heiberger

## See Section 12.1.4.2 of
## Richard M. Heiberger
## Computation for the Analysis of Designed Experiments
## Wiley, 1989



## defaults to 8 bit binary

base <- function(x, basis=c(2,2,2,2,2,2,2,2)) {
  cb <- rev(cumprod(c(1,basis)))
  xx <- x
  y <- rep(0, length(cb))  
  for (i in 1:length(cb)) {
    yy <- xx %/% cb[i]
    if (yy > 0) {
      y[i] <- yy
      xx <- xx %% cb[i]
    }
  }
  names(y) <- cb
  y
}

baseinv <- function(y, basis=c(2,2,2,2,2,2,2,2)) {
  sum(y * rev(cumprod(c(1,basis))))
}


base(200)
baseinv(.Last.value)


## British money
basis <- c(12,20)  ## 12 pence per shilling, 20 shillings per pound sterling
base(498, basis)
baseinv(.Last.value, basis)

## American weight
base(100, 16)      ## 16 ounces per pound avoirdupois
baseinv(.Last.value, 16)

## time
basis <- c(60,60,24) ## 60 seconds per minute, 60 minutes per hour, 24 hours per day
x <- c(1, 2, 3, 40)
y <- baseinv(x, basis)
y
base(y, basis)


## binary arithmetic with 8 bits

basis <- c(2,2,2,2,2,2,2,2)
x <- 100

y <- base(x, basis)
y
baseinv(y, basis)

base(1)
baseinv(.Last.value)

base(200)
baseinv(.Last.value)

base(1000)
baseinv(.Last.value)




## IEEE with 53 base 2 digits
x <- c(  100000000000001,   100000000000002,   100000000000003,
        1000000000000001,  1000000000000002,  1000000000000003,
       10000000000000001, 10000000000000002, 10000000000000003 ## the last three values illustrate
       )                                                       ## the effects of .Machine$double.eps
x
sprintf("%17.0f", x)

y <- sapply(x, base, basis=rep(2,54))
y

print(digits=17,
      apply(y, 2, baseinv, basis=rep(2,54))
      )



## base 9
a <- base(132, c(9,9,9))
b <- base(125, c(9,9,9))
a
b
a+b
baseinv(a+b, c(9,9,9))
base(baseinv(a+b, c(9,9,9)), c(9,9,9))


More information about the R-help mailing list