How to do bitwise ops on a byte?

Hello,
I can’t seem to find a way to do bitwise ops on a
byte, at least using the standard library. In fact,
when the bytes from a string are converted to
integers, they are converted to platform dependent
integers, so one might argue that it is impossible to
do any platform independent bitwise ops in a
straightforward way in ruby.

The nature of bitwise ops is one that requires a solid
grasp of what it is you’re manipulating. I would argue
that bitwise ops should be removed from fixnum and
bignum. Instead, have a class representing a bit field
of arbitrary size that can be converted back to an
integer or anything else that can be constructed with
a fixed number of bits --especially a byte.

Perhaps some would argue that adding every conceivable
integer type to standard ruby would make it ugly, and
I would tend to agree, but I think the byte deserves
special consideration. Ruby strings are 8 bit clean
which is such a beautiful thing, and ruby docs state
that strings can hold arbitrary data, but how would
you get the data from a string if every byte is
converted to a native integer? There doesn’t seem to
be an “unpack” function that returns an array of
bytes.

Maybe just add bitwise ops to strings? That way, you
don’t even need a byte datatype, so long as there is a
way to unpack a string into an array of strings where
each string is 1 byte, and that this is not
complicated by any future attempts to turn a string
into a sequence of UTF-8 characters or some such
thing.

As a side note, I find a lot of the unpack functions
to be just weird. I don’t understand what “B” and “b”
are good for. They extract bits but return an array
with 1 element that is a string containing the
characters “1” and “0”, but those are not really bits,
and are not useful for bitwise operations.

I love the design of ruby. Please don’t make me have
to use C or Java just because I want to do some
bitwise ops. It’s just a harmless codec I’m working on
:slight_smile: Actually I already did it in Java :frowning:

Bernard

···

Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

Bernard Miller wrote:

The nature of bitwise ops is one that requires a solid
grasp of what it is you’re manipulating. I would argue
that bitwise ops should be removed from fixnum and
bignum. Instead, have a class representing a bit field
of arbitrary size that can be converted back to an
integer or anything else that can be constructed with
a fixed number of bits --especially a byte.

I think Robert Feldt’s BitVector extension module:

 http://www.ruby-lang.org/raa/list.rhtml?name=bitvector

provides what you’re describing.

I can?t seem to find a way to do bitwise ops on a
byte, at least using the standard library. […]

I was just doing bitwise ops last night. What are you trying
to do?

As a side note, I find a lot of the unpack functions
to be just weird. I don?t understand what ?B? and ?b?
are good for. They extract bits but return an array
with 1 element that is a string containing the
characters ?1? and ?0?, but those are not really bits,
and are not useful for bitwise operations.

The “b” and “B” operators simply return string representations
in base 2.

123.chr.unpack(“B8”) # => [“01111011”]

Take the value 123 and return the 8-bit string representation of
it in binary, which is 01111011.

Alternatively:

sprintf “%8b”, 123 # => “01111011”

I love the design of ruby. Please don?t make me have
to use C or Java just because I want to do some
bitwise ops. It?s just a harmless codec I?m working on
:slight_smile: Actually I already did it in Java :frowning:

b = 123 # which we know is 01111011

if we want to test for bit 4, we bitwise-and with 0x08 and

test to make sure it doesn’t equal 0:

if b & 0x08 != 0
puts “bit 4 set”
end

if we want to test that bit 3 is clear, we bitwise-and

with 0x04 and make sure it equals 0:

if b & 0x04 == 0
puts “bit 3 clear”
end

If we want to now set bit 3, we bitwise-or the value 0x04:

b = b | 0x04

p b # => 127, or “01111111” which is 01111011 with bit 3 now set.

– Dossy

···

On 2002.12.31, Bernard Miller forbytext@yahoo.com wrote:


Dossy Shiobara mail: dossy@panoptic.com
Panoptic Computer Network web: http://www.panoptic.com/
“He realized the fastest way to change is to laugh at your own
folly – then you can let go and quickly move on.” (p. 70)

Bernard Miller forbytext@yahoo.com writes:

I can’t seem to find a way to do bitwise ops on a
byte, at least using the standard library. In fact,
when the bytes from a string are converted to
integers, they are converted to platform dependent
integers, so one might argue that it is impossible to
do any platform independent bitwise ops in a
straightforward way in ruby.

Perhaps not related to what you are looking for, but I have written a
bit construction, matching, and extraction module.

http://www.ruby-lang.org/raa/list.rhtml?id=775

Yours,
YS.

This works for simple bit masking operations, but I’m
shifting bits a lot. I need to know the total number
of bits I’m dealing with, not just the number of bits
that can be assumed from the size of the number. I
also need to know the exact order of bits, not just an
order relative to the most significant bit which is
all you really know when dealing with values instead
of bit patterns.

The bitvector interface is probably overkill for what
I want to do, and I seem to need to know perl to
understand the documentation, but I’ll look into it
and post a comparison when I’m finished.

Thanks for the replies.

Bernard

···

— Dossy dossy@panoptic.com wrote:

b = 123 # which we know is 01111011

if we want to test for bit 4, we bitwise-and with

0x08 and

test to make sure it doesn’t equal 0:

if b & 0x08 != 0
puts "b
end


Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.

Why not create your own BitString class? If you can define
the number of operations …

class BitString
def initialize(length)
# length is the length of the bitstring, in bits
@length = length
# @bits contains the string of bits – initialize to 0.
@bits = sprintf “%0#{@length}b”, 0
end

def =(value)
@bits = sprintf “%0#{@length}b”, value
end

def >>(times)
# shift right ‘times’ times.
…add code…
end

def <<(times)
# shift left ‘times’ times.
…add code…
end

def +(other)
# add two bitstrings together
…add code…
end

…add code for other bitwise operations you need to support…

def to_s
@bits
end
end

You get the idea …

– Dossy

···

On 2003.01.02, Bernard Miller forbytext@yahoo.com wrote:

This works for simple bit masking operations, but I?m
shifting bits a lot. I need to know the total number
of bits I?m dealing with, not just the number of bits
that can be assumed from the size of the number. I
also need to know the exact order of bits, not just an
order relative to the most significant bit which is
all you really know when dealing with values instead
of bit patterns.

The bitvector interface is probably overkill for what
I want to do, and I seem to need to know perl to
understand the documentation, but I?ll look into it
and post a comparison when I?m finished.


Dossy Shiobara mail: dossy@panoptic.com
Panoptic Computer Network web: http://www.panoptic.com/
“He realized the fastest way to change is to laugh at your own
folly – then you can let go and quickly move on.” (p. 70)