How convert an integer to a bit array

C

Curt Hibbs

------=_Part_4391_5030105.1132698217184
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Does anyone have a clever way to convert an integer to an array of bit
values?

For example (using 8 bit integers):

0 =3D> [0, 0, 0, 0, 0, 0, 0, 0]
1 =3D> [0, 0, 0, 0, 0, 0, 0, 1]
2 =3D> [0, 0, 0, 0, 0, 0, 1, 0]
7 =3D> [0, 0, 0, 0, 0, 1, 1, 1]
etc.

I was looking at Array#pack and Array#unpack to do this, but haven't figure=
d
it out yet. It just seems like there ought to be a simple way to do this.

Anybody got a clever idea?

Curt

------=_Part_4391_5030105.1132698217184--
 
D

Daniel Schüle

Curt said:
Does anyone have a clever way to convert an integer to an array of bit
values?

For example (using 8 bit integers):

0 => [0, 0, 0, 0, 0, 0, 0, 0]
1 => [0, 0, 0, 0, 0, 0, 0, 1]
2 => [0, 0, 0, 0, 0, 0, 1, 0]
7 => [0, 0, 0, 0, 0, 1, 1, 1]
etc.

I was looking at Array#pack and Array#unpack to do this, but haven't figured
it out yet. It just seems like there ought to be a simple way to do this.

Anybody got a clever idea?

Curt

irb(main):082:0> x = 7.to_s(2).split(//).map! {|bit| bit.to_i}
=> [1, 1, 1]
irb(main):083:0> x.unshift(0) until x.length == 8

if your number always fit into 8 bit
otherwise this doesn't work

Regards, Daniel
 
J

James Edward Gray II

Does anyone have a clever way to convert an integer to an array of bit
values?

For example (using 8 bit integers):

0 => [0, 0, 0, 0, 0, 0, 0, 0]
1 => [0, 0, 0, 0, 0, 0, 0, 1]
2 => [0, 0, 0, 0, 0, 0, 1, 0]
7 => [0, 0, 0, 0, 0, 1, 1, 1]
etc.

I was looking at Array#pack and Array#unpack to do this, but
haven't figured
it out yet. It just seems like there ought to be a simple way to do
this.

Anybody got a clever idea?

Does this help?
=> [1, 0, 1]

James Edward Gray II
 
J

Joel VanderWerf

Curt said:
Does anyone have a clever way to convert an integer to an array of bit
values?

For example (using 8 bit integers):

0 => [0, 0, 0, 0, 0, 0, 0, 0]
1 => [0, 0, 0, 0, 0, 0, 0, 1]
2 => [0, 0, 0, 0, 0, 0, 1, 0]
7 => [0, 0, 0, 0, 0, 1, 1, 1]
etc.

I was looking at Array#pack and Array#unpack to do this, but haven't figured
it out yet. It just seems like there ought to be a simple way to do this.

Anybody got a clever idea?

Curt


s = ""
s[0] = 7
s.unpack("B*")[0].split("").map{|bit|bit.to_i}
=> [0, 0, 0, 0, 0, 1, 1, 1]



It should be easier than that, though.
 
M

Marcel Molina Jr.

Does anyone have a clever way to convert an integer to an array of bit
values?

For example (using 8 bit integers):

0 => [0, 0, 0, 0, 0, 0, 0, 0]
1 => [0, 0, 0, 0, 0, 0, 0, 1]
2 => [0, 0, 0, 0, 0, 0, 1, 0]
7 => [0, 0, 0, 0, 0, 1, 1, 1]
etc.

I was looking at Array#pack and Array#unpack to do this, but
haven't figured
it out yet. It just seems like there ought to be a simple way to do
this.

Anybody got a clever idea?

Does this help?
=> [1, 0, 1]

An alternative to ('%b' % n) is n.to_s(2)

marcel
 
C

Caleb Tennis

s = ""
s[0] = 7
s.unpack("B*")[0].split("").map{|bit|bit.to_i}
=> [0, 0, 0, 0, 0, 1, 1, 1]



It should be easier than that, though.

How about:

num = 50

num.to_s(2).split("").map{ |bit| bit.to_i}

There's problably some trickery with String.each_with_index you can
do to make the map a little simpler.
 
M

Marcel Molina Jr.

Curt said:
Does anyone have a clever way to convert an integer to an array of bit
values?

For example (using 8 bit integers):

0 => [0, 0, 0, 0, 0, 0, 0, 0]
1 => [0, 0, 0, 0, 0, 0, 0, 1]
2 => [0, 0, 0, 0, 0, 0, 1, 0]
7 => [0, 0, 0, 0, 0, 1, 1, 1]
etc.

I was looking at Array#pack and Array#unpack to do this, but haven't
figured
it out yet. It just seems like there ought to be a simple way to do this.

Anybody got a clever idea?

Curt

irb(main):082:0> x = 7.to_s(2).split(//).map! {|bit| bit.to_i}
=> [1, 1, 1]
irb(main):083:0> x.unshift(0) until x.length == 8

if your number always fit into 8 bit
otherwise this doesn't work

You could do this:

x.unshift(0) until (x.size % 8).zero?

marcel
 
D

Daniel Berger

Marcel said:
Curt said:
Does anyone have a clever way to convert an integer to an array of bit
values?

For example (using 8 bit integers):

0 => [0, 0, 0, 0, 0, 0, 0, 0]
1 => [0, 0, 0, 0, 0, 0, 0, 1]
2 => [0, 0, 0, 0, 0, 0, 1, 0]
7 => [0, 0, 0, 0, 0, 1, 1, 1]
etc.

I was looking at Array#pack and Array#unpack to do this, but haven't
figured
it out yet. It just seems like there ought to be a simple way to do this.

Anybody got a clever idea?

Curt

irb(main):082:0> x = 7.to_s(2).split(//).map! {|bit| bit.to_i}
=> [1, 1, 1]
irb(main):083:0> x.unshift(0) until x.length == 8

if your number always fit into 8 bit
otherwise this doesn't work


You could do this:

x.unshift(0) until (x.size % 8).zero?

marcel

Nah, that's too much work.

x = ("%08d" % 7.to_s(2)).split('').map{ |e| e.to_i }

Replace 8 with the integer size and 7 with whatever number you're converting.

Regards,

Dan
 
R

Ryan Leavengood

Does anyone have a clever way to convert an integer to an array of bit
values?

For example (using 8 bit integers):

0 =3D> [0, 0, 0, 0, 0, 0, 0, 0]
1 =3D> [0, 0, 0, 0, 0, 0, 0, 1]
2 =3D> [0, 0, 0, 0, 0, 0, 1, 0]
7 =3D> [0, 0, 0, 0, 0, 1, 1, 1]
etc.

I was looking at Array#pack and Array#unpack to do this, but haven't figu= red
it out yet. It just seems like there ought to be a simple way to do this.

Anybody got a clever idea?

This way is about 4 times faster than James' version:

class Integer
def to_ba(size=3D8)
a=3D[]
(size-1).downto(0) do |i|
a<<self
end
a
end
end

p 0.to_ba
p 1.to_ba
p 2.to_ba
p 7.to_ba
__END__

Result:

[0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 1, 1, 1]

Ryan
 
R

Ryan Leavengood

This way is about 4 times faster than James' version:

For those curious:

----------------------------------------------------------------------
| QuickBench Session Started |
| 100000 Iterations |
----------------------------------------------------------------------
user system total real
1. 244.to_ba 1.171000 0.000000 1.171000 ( 1.172000)
2. ("%b" % 244).split(... 4.735000 0.000000 4.735000 ( 4.750000)
3. s.unpack("B*")[0].s... 4.156000 0.000000 4.156000 ( 4.156000)
4. 244.to_s(2).split("... 4.422000 0.000000 4.422000 ( 4.437000)
----------------------------------------------------------------------
| Fastest was <1. 244.to_ba> |
----------------------------------------------------------------------

QuickBench is a little script I wrote, which I may or may not release
into the wild.

The code will follow my name (note how I use the DATA section for the
things to benchmark):

Ryan "Mr. Benchmark" Leavengood

class Integer
def to_ba(size=3D8)
a=3D[]
(size-1).downto(0) do |i|
a<<self
end
a
end
end

require 'quickbench'
s=3D" "
s[0]=3D244
QuickBench.go(100000, 22) {}
__END__
244.to_ba
("%b" % 244).split("").map { |n| n.to_i }
s.unpack("B*")[0].split("").map{|bit|bit.to_i}
244.to_s(2).split("").map{ |bit| bit.to_i}
 
J

James Edward Gray II

Does anyone have a clever way to convert an integer to an array of bit
values?

For example (using 8 bit integers):

0 => [0, 0, 0, 0, 0, 0, 0, 0]
1 => [0, 0, 0, 0, 0, 0, 0, 1]
2 => [0, 0, 0, 0, 0, 0, 1, 0]
7 => [0, 0, 0, 0, 0, 1, 1, 1]
etc.

I was looking at Array#pack and Array#unpack to do this, but
haven't figured
it out yet. It just seems like there ought to be a simple way to do
this.

Anybody got a clever idea?

Another thought: Ruby's Integers are already pretty close to a bit
Array. If you only need to index the bits, maybe it's best not to
convert at all...

James Edward Gray II
 
J

James Edward Gray II

Does anyone have a clever way to convert an integer to an array of bit
values?

For example (using 8 bit integers):

0 => [0, 0, 0, 0, 0, 0, 0, 0]
1 => [0, 0, 0, 0, 0, 0, 0, 1]
2 => [0, 0, 0, 0, 0, 0, 1, 0]
7 => [0, 0, 0, 0, 0, 1, 1, 1]
etc.

I was looking at Array#pack and Array#unpack to do this, but
haven't figured
it out yet. It just seems like there ought to be a simple way to do
this.

Anybody got a clever idea?

Last idea:
bits = Array.new(8) { |i| 7 }.reverse!

=> [0, 0, 0, 0, 0, 1, 1, 1]

I promise to stop spamming this thread now. ;)

James Edward Gray II
 
C

Curt Hibbs

------=_Part_5746_1339316.1132747729698
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

You guys are awesome... so many good ideas here!

Thanks,
Curt

------=_Part_5746_1339316.1132747729698--
 
R

Ryan Leavengood

bits =3D Array.new(8) { |i| 7 }.reverse!

=3D> [0, 0, 0, 0, 0, 1, 1, 1]


And the winner by a nose is.................................
...............................
...............................
James!!!

----------------------------------------------------------------------
| QuickBench Session Started |
| 300000 Iterations |
----------------------------------------------------------------------
user system total real
1. 244.to_ba 3.296000 0.015000 3.311000 ( 3.313000)
2. Array.new(8) { |i| ... 2.782000 0.000000 2.782000 ( 2.781000)
----------------------------------------------------------------------
| Fastest was <2. Array.new(8) { |i| ...> |
----------------------------------------------------------------------

I'm glad you posted this because it is elegant and fast. OK, now I'll
stop spamming this thread with benchmark results :)

Regards,
Ryan
 
C

Curt Hibbs

------=_Part_10684_6246159.1132770497044
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

bits =3D Array.new(8) { |i| 7 }.reverse!

=3D> [0, 0, 0, 0, 0, 1, 1, 1]


And the winner by a nose is.................................
...............................
...............................
James!!!


Cool! Thanks for doing the benchmark.

Curt

------=_Part_10684_6246159.1132770497044--
 
E

Ed Howland

bits =3D Array.new(8) { |i| 7 }.reverse!
=3D> [0, 0, 0, 0, 0, 1, 1, 1]


And the winner by a nose is ...
James!!!


def to_ba(num, size=3D8)
(-size+1..0).inject({}) {|x,i| x << num[-i]}
end

to_ba(15)
=3D> [0,0,0,0,1,1,1,1]

It may be a tad faster, the bigger the array, due to the lack of
reverse. Can someone bench it? I don't have require 'quickbench'

Or perhaps, modifying James':

def to_ba(num, size=3D8)
Array.new(size) {|i| num[-i+size-1]}
end

Ed
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top