[R] bitwise addition

Marc Schwartz (via MN) mschwartz at mn.rr.com
Fri May 12 21:50:52 CEST 2006


On Fri, 2006-05-12 at 14:05 -0500, Marc Schwartz (via MN) wrote:
> On Fri, 2006-05-12 at 11:41 -0500, Nameeta Lobo wrote:
> > 
> > Hello all again,
> > 
> > I want to do bitwise addition in R. I am trying to generate a matrix
> > 0000
> > 0001
> > 0010
> > ....
> > ....
> > 1111
> > 
> > I know the other ways of generating this matrix but I need to look at bitwise
> > addition. 
> > 
> > Any suggestions???
> > 
> > thanks a lot
> > 
> > Nameeta
> 
> Nameeta,
> 
> I may be misunderstanding what you are trying to do, so here are two
> approaches that might be helpful:
> 
> 1. Presuming that each of the above rows is a binary representation of a
> number x >= 0 (so we don't have to worry about two's complements) and
> that you want to add the rows to get a total, you can do:
> 
> > mat
>      [,1] [,2] [,3] [,4]
> [1,]    0    0    0    0
> [2,]    0    0    0    1
> [3,]    0    0    1    0
> [4,]    1    1    1    1
> 
> # This will convert each row to it's base 10 value
> > apply(mat, 1, function(x) sum(x * (2 ^ ((length(x) - 1):0))))
> [1]  0  1  2 15
> 
> # So just sum them
> > sum(apply(mat, 1, function(x) sum(x * (2 ^ ((length(x) - 1):0)))))
> [1] 18
> 
> 
> 2. If you want to actually generate the above matrix as a sequence of
> binary values from a sequence of base 10 integer values, you can use the
> digitsBase() function in Martin's sfsmisc package on CRAN:
> 
> install.packages("sfsmisc")
> library(sfsmisc)
> 
> > t(digitsBase(1:15))
> Class 'basedInt'(base = 2) [1:4]
>       [,1] [,2] [,3] [,4]
>  [1,]    0    0    0    1
>  [2,]    0    0    1    0
>  [3,]    0    0    1    1
>  [4,]    0    1    0    0
>  [5,]    0    1    0    1
>  [6,]    0    1    1    0
>  [7,]    0    1    1    1
>  [8,]    1    0    0    0
>  [9,]    1    0    0    1
> [10,]    1    0    1    0
> [11,]    1    0    1    1
> [12,]    1    1    0    0
> [13,]    1    1    0    1
> [14,]    1    1    1    0
> [15,]    1    1    1    1


One quick notation here. I just noted that Martin has an as.integer()
method for the basedInt class above. This allows for converting the
numbers back to base 10 representation. It presumes that the number to
be converted is the column, not the row. Thus the transpose of the
matrix above results in:

> as.integer(t(digitsBase(1:15)))
    1     2     3     4
  255  3855 13107 21845

If you of course leave the matrix as is (as Martin clearly intended),
you get:

> digitsBase(1:15)
Class 'basedInt'(base = 2) [1:15]
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,]    0    0    0    0    0    0    0    1    1     1     1     1
[2,]    0    0    0    1    1    1    1    0    0     0     0     1
[3,]    0    1    1    0    0    1    1    0    0     1     1     0
[4,]    1    0    1    0    1    0    1    0    1     0     1     0
     [,13] [,14] [,15]
[1,]     1     1     1
[2,]     1     1     1
[3,]     0     1     1
[4,]     1     0     1

and therefore:

> as.integer(digitsBase(1:15))
 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15


This would make basic arithmetic operations easier. Generating 'mat'
above for example:

> mat <- digitsBase(c(0:2, 15))

# Again, note that each number is a column
# not the row
> mat
Class 'basedInt'(base = 2) [1:4]
     [,1] [,2] [,3] [,4]
[1,]    0    0    0    1
[2,]    0    0    0    1
[3,]    0    0    1    1
[4,]    0    1    0    1

> as.integer(mat)
 1  2  3  4
 0  1  2 15


Finally:

> sum(as.integer(mat))
[1] 18

and back to binary:

> digitsBase(sum(as.integer(mat)))
Class 'basedInt'(base = 2) [1:1]
     [,1]
[1,]    1
[2,]    0
[3,]    0
[4,]    1
[5,]    0

or even as a character vector:

> paste(digitsBase(sum(as.integer(mat))), collapse = "")
[1] "10010"


HTH,

Marc Schwartz




More information about the R-help mailing list