Equivalent bitget function in R - r

Is there a function in R that performs the same operation as bitget in MatLab/Octave:
bitget

From the bitget help page
Return the status of bit(s) n of unsigned integers in A the
lowest significant bit is n = 1.
bitget (100, 8:-1:1)
⇒ 0 1 1 0 0 1 0 0
so if you want to get the bit values for an integer in R, you can do
intToBits(100)[8:1]
# [1] 00 01 01 00 00 01 00 00
That technically returns a raw vector, so if you want just a numeric vector, do
as.numeric(intToBits(100)[8:1])
# [1] 0 1 1 0 0 1 0 0

Related

Hmmm Assembly Fibonacci Sequence

I need to write and print out the Fibonacci sequence up to a given integer (can choose yourself)
I have to do this in Hmmm... Assembly
It gets stuck in infinite recursion, but I have no idea why
00 read r4 # User input
01 setn r4 -1 # adds -1 to r4
02 setn r1 1 # r1 == 1
03 setn r2 0 # r2 == 0
04 setn r5 1 # used as the first number of the fibonacci sequence
05 write r5 # 1
06 jeqzn r4 13 # if r4 == 0, the fibonacci sequence stops
07 add r3 r1 r2 # r3 = r1 + r2
08 addn r4 -1 # r4 = r4 -1
09 copy r2 r1 # r2 now equals r1
10 copy r1 r3 # r1 nog equals r3
11 write r3 # prints fibonacci number
12 jumpn 06 # checks if r4 == 0
13 halt # stops
current output:
1
1
2
3
5
8
13
21
34
55
89
144
233
377
..
..
Wanted output (example): if input (r4) = 10
1
1
2
3
5
8
13
21
34
55
08 addn r4 -1 (r4 should eventually end up being 0)
06 jeqzn r4 13 (should check when it's true, and it should halt)
What prevents it from halting?
Looks like line 1 sets r4 (the input) to -1 instead of the desired subtracting 1, so it should be addn r4 -1.
It's also worth noting the current implementation is iterative and not recursive, and the loop doesn't appear to be infinite but just really long as it would have to count down from -1 to wrap around to 0 (assuming addn does not saturate).

How to represent 4 bit integers properly?

I need to convert a matrix to a hex file output. Each entry in the matrix needs to get translated to a 4 bit hex digit (8) and output in a single dimension array.
> matrix(c(0,0,0,5,0,0,5,5,0,0,5,0),nrow=3,ncol=4,byrow=T)
[,1] [,2] [,3] [,4]
[1,] 0 0 0 5
[2,] 0 0 5 5
[3,] 0 0 5 0
This is a 3 row, 4 column matrix with mostly 0s and some 5s. My desired output should be something similar to
#> as.raw(c(0,8,0,136,0,128))
> as.raw(solution)
[1] 00 08 00 88 00 80
I was trying to do some simple
> sidewaysraw<-as.raw(ifelse(mymat==5, 8,0))
but the 8 in the ifelse of course is a 16 bit integer, so it's always an 0x08. I don't see a slick way to translate 55s to 0x88s, 05s to 0x08s and 50s to 0x80s...
Is there a smooth way to get R to work with 4 bit integers?
It seems like you could do some matrix multiplication to help. First we can define a "translation matrix"
digits <- matrix(c(128,8,0,0,0,0,128,8), nrow=4, ncol=2)
Then you can get your numbers out with
(dd==5) %*% digits
# [,1] [,2]
# [1,] 0 8
# [2,] 0 136
# [3,] 0 128
and then extract them in the right order with a transposition
as.raw(t((dd==5) %*% digits))
# [1] 00 08 00 88 00 80
This should be efficient and doesn't bother with string manipulation.
Assuming I understood your question correctly, this solves your problem:
mat <- matrix(c(0,0,0,5,0,0,5,5,0,0,5,0),nrow=3,ncol=4,byrow=T)
mat_new <- matrix(t(mat),ncol=2,byrow=T) #reformat to 2 columns
vec <- apply(mat_new,1,function(row)
{
num <- paste0(row,collapse="") #collapse the rows
if(num == "00") return(as.raw(0)) #switch the resulting char
else if(num == "05") return(as.raw(8))
else if(num == "50") return(as.raw(128))
else if(num == "55") return(as.raw(136))
})
vec
[1] 00 08 00 88 00 80

Subsetting data using grep

I have a dataframe named Schedule which has data for multiple airlines. I run the table function just to get the breakdown of records by airlines. Here is the answer
table(Schedule$airline)
AA AS B6 BA DL F9 FI LH NK QR UA WN
757 4 14 2 65 24 2 2 18 2 36 60
Now I am subsetting this data using grep to get a data frame which has gates in a particular terminal of interest, which in this case is terminal F
Gated_Schedule <- Schedule[grep("F", Schedule$gate), ]
when I run table to get a breakdown here,
table(Gated_Schedule$airline)
AA AS B6 BA DL F9 FI LH NK QR UA WN
362 0 0 0 0 0 0 0 0 0 0 0
Ideally the output should only have been AA like:
AA
362
How do I get rid of this discrepancy?

how to optimize away common subexpressions?

select x+y as z,
case
when "x"+"y" < 0 then "Less Than Zero"
when "x"+"y" > 0 then "Non Zero"
else "Zero"
end
from sometable;
Returns expected result, but the addition is done with each row of data multiple times.
I am trying to optimize the query as follows but not working..
select x+y as z,
case
when "z" < 0 then "Less Than Zero"
when "z" > 0 then "Non Zero"
else "Zero"
end
from sometable;
Always returns "Less Than Zero".
What am I doing wrong on this query? How can I avoid adding A and B multiple times while the query is being executed?
Column aliases in the SELECT clause are not available in other expressions in the same SELECT clause. (What should happen with SELECT x AS y, y AS x ...?)
You can make such an alias available by moving it into a subquery:
SELECT z,
CASE WHEN z < 0 THEN 'Less Than Zero'
WHEN z > 0 THEN 'Non Zero'
ELSE 'Zero'
END
FROM (SELECT x + y AS z
FROM sometable);
However, this only saves typing; it does not actually optimize away the duplicate computation:
sqlite> explain select z, z from (select x+y as z from sometable);
addr opcode p1 p2 p3 p4 p5 comment
---- ------------- ---- ---- ---- ------------- -- -------------
0 Init 0 11 0 00 Start at 11
1 OpenRead 1 2 0 2 00 root=2 iDb=0; sometable
2 Rewind 1 9 0 00
3 Column 1 0 3 00 r[3]=sometable.x
4 Column 1 1 4 00 r[4]=sometable.y
5 Add 4 3 1 00 r[1]=r[4]+r[3]
6 Add 4 3 2 00 r[2]=r[4]+r[3]
7 ResultRow 1 2 0 00 output=r[1..2]
8 Next 1 3 0 01
9 Close 1 0 0 00
10 Halt 0 0 0 00
11 Transaction 0 0 1 0 01 usesStmtJournal=0
12 TableLock 0 2 0 sometable 00 iDb=0 root=2 write=0
13 Goto 0 1 0 00

Convert binary string to binary or decimal value

Is there any function to convert binary string into binary or decimal value?
If I have a binary string 000101, what should I do to convert it into 5?
You could use the packBits function (in the base package). Bear in mind that this function requires very specific input.
(yy <- intToBits(5))
# [1] 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# [26] 00 00 00 00 00 00 00
# Note that there are 32 bits and the order is reversed from your example
class(yy)
[1] "raw"
packBits(yy, "integer")
# [1] 5
There is also the strtoi function (also in the base package):
strtoi("00000001001100110000010110110111", base = 2)
# [1] 20121015
strtoi("000101", base = 2)
# [1] 5
Here is what you can try:
binStr <- "00000001001100110000010110110111" # 20121015
(binNum <- 00000001001100110000010110110111) # 20121015
[1] 1.0011e+24
binVec <- c(1,0,1,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1) # 2670721
shortBin <- 10011010010 # 1234
BinToDec <- function(x)
sum(2^(which(rev(unlist(strsplit(as.character(x), "")) == 1))-1))
BinToDec(binStr)
[1] 20121015
BinToDec(binNum)
[1] 576528
BinToDec(binVec)
[1] 2670721
BinToDec(shortBin)
[1] 1234
That is, you can input both strings (because of as.character()) and numeric binary values but there are some problems with large numbers like binNum. As I understand you also want to convert binary string to numeric binary values, but unfortunately there is no such data type at least in base R.
Edit: Now BinToDec also accepts binary vectors, which might be a solution for large numbers. Function digitsBase() from package sfsmisc returns such a vector:
(vec <- digitsBase(5, base= 2, 10))
Class 'basedInt'(base = 2) [1:1]
[,1]
[1,] 0
[2,] 0
[3,] 0
[4,] 0
[5,] 0
[6,] 0
[7,] 0
[8,] 1
[9,] 0
[10,] 1
BinToDec(vec)
[1] 5
Finally, another possibility is package compositions , for example:
(x <- unbinary("10101010"))
[1] 170
(y <- binary(x))
[1] "10101010"
base::strtoi(binary_string, base = 2)
This function calculates the decimal version with a flexible base. Base equals 2 is binary, etc. This should work up until a base of 10.
base2decimal = function(base_number, base = 2) {
split_base = strsplit(as.character(base_number), split = "")
return(sapply(split_base, function(x) sum(as.numeric(x) * base^(rev(seq_along(x) - 1)))))
}
> base2decimal(c("000101", "00000001001100110000010110110111"))
[1] 5 20121015
In the case that you have binary string, all of the prior answers are great. I often find myself in situations where I want to encode a combination of binary vectors. The logic of translating from a combination of 0's and 1's to an integer is always the same:
bincount <- function(B, base=2) { return(B %*% base^seq(0,ncol(B)-1)) }
Where B is a matrix, and each column is a binary vector.
Example:
isBig <- c(0, 1, 0, 1)
isRed <- c(0, 0, 1, 1)
B = cbind(isBig,isRed)
bincount(B)
# 0 1 2 3

Resources