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
On Nov 22, 2005, at 4:23 PM, Curt H. wrote:
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?
("%b" % 5).split("").map { |n| n.to_i }
=> [1, 0, 1]
James Edward G. II
Curt H. wrote:
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.
On Wed, Nov 23, 2005 at 07:31:02AM +0900, James Edward G. II wrote:
7 => [0, 0, 0, 0, 0, 1, 1, 1]
("%b" % 5).split("").map { |n| n.to_i }
=> [1, 0, 1]
An alternative to (’%b’ % n) is n.to_s(2)
marcel
Curt H. wrote:
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
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.
Marcel Molina Jr. wrote:
1 => [0, 0, 0, 0, 0, 0, 0, 1]
Curt
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
On Wed, Nov 23, 2005 at 07:37:25AM +0900, Daniel Sch?le wrote:
etc.
=> [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
On 11/22/05, Curt H. [email protected] wrote:
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?
This way is about 4 times faster than James’ version:
class Integer
def to_ba(size=8)
a=[]
(size-1).downto(0) do |i|
a<<self[i]
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
On 11/22/05, Ryan L. [email protected] wrote:
This way is about 4 times faster than James’ version:
For those curious:
| QuickBench Session Started |
user system total real
- 244.to_ba 1.171000 0.000000 1.171000 ( 1.172000)
- (“%b” % 244).split(… 4.735000 0.000000 4.735000 ( 4.750000)
- s.unpack(“B*”)[0].s… 4.156000 0.000000 4.156000 ( 4.156000)
- 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=8)
a=[]
(size-1).downto(0) do |i|
a<<self[i]
end
a
end
end
require ‘quickbench’
s=" "
s[0]=244
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}
On Nov 22, 2005, at 4:23 PM, Curt H. wrote:
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 G. II
You guys are awesome… so many good ideas here!
Thanks,
Curt
On 11/22/05, James Edward G. II [email protected] wrote:
bits = Array.new(8) { |i| 7[i] }.reverse!
=> [0, 0, 0, 0, 0, 1, 1, 1]
And the winner by a nose is…
…
…
James!!!
| QuickBench Session Started |
user system total real
- 244.to_ba 3.296000 0.015000 3.311000 ( 3.313000)
- 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
On 11/23/05, Ryan L. [email protected] wrote:
I’m glad you posted this because it is elegant and fast. OK, now I’ll
stop spamming this thread with benchmark results
Cool! Thanks for doing the benchmark.
Curt
On 11/23/05, Curt H. [email protected] wrote:
On 11/23/05, Ryan L. [email protected] wrote:
On 11/22/05, James Edward G. II [email protected] wrote:
bits = Array.new(8) { |i| 7[i] }.reverse!
=> [0, 0, 0, 0, 0, 1, 1, 1]
And the winner by a nose is
…
James!!!
def to_ba(num, size=8)
(-size+1…0).inject({}) {|x,i| x << num[-i]}
end
to_ba(15)
=> [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=8)
Array.new(size) {|i| num[-i+size-1]}
end
Ed
On Nov 22, 2005, at 4:23 PM, Curt H. wrote:
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[i] }.reverse!
=> [0, 0, 0, 0, 0, 1, 1, 1]
I promise to stop spamming this thread now.
James Edward G. II