Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > negative numbers and binary formats

Reply
Thread Tools

negative numbers and binary formats

 
 
Paul
Guest
Posts: n/a
 
      09-22-2004
Im trying to take a negative integer value, convert it to its binary
equivalent, and save its hex value

-7 -> 1111 1001 -> F9


I was hoping to use sprintf, but:

irb(main):017:0> b = sprintf("%4b" , a)
=> "..1001"
irb(main):018:0>

The .. that appear break any further processing. So my questions are:

Why the dots, and what are they?
How do I do what Im trying to do - given my -7 in the example may be a
1 byte, 2 byte or 4 byte value. ( Im sure its some magic with
pack....)

Thanks

Paul
 
Reply With Quote
 
 
 
 
Florian Gross
Guest
Posts: n/a
 
      09-22-2004
Paul wrote:

Moin!

> Im trying to take a negative integer value, convert it to its binary
> equivalent, and save its hex value
>
> -7 -> 1111 1001 -> F9


Does this help?

irb(main):032:0> [-7].pack("c").unpack("H*").first
=> "f9"

> Thanks
> Paul


Regards,
Florian Gross
 
Reply With Quote
 
 
 
 
Ara.T.Howard@noaa.gov
Guest
Posts: n/a
 
      09-22-2004
On Wed, 22 Sep 2004, Paul wrote:

> Im trying to take a negative integer value, convert it to its binary
> equivalent, and save its hex value
>
> -7 -> 1111 1001 -> F9
>
>
> I was hoping to use sprintf, but:
>
> irb(main):017:0> b = sprintf("%4b" , a)
> => "..1001"
> irb(main):018:0>
>
> The .. that appear break any further processing. So my questions are:
>
> Why the dots, and what are they?
> How do I do what Im trying to do - given my -7 in the example may be a
> 1 byte, 2 byte or 4 byte value. ( Im sure its some magic with
> pack....)
>
> Thanks
>
> Paul


you have a couple of options:

the [] method of Fixnum returns the bit:

harp:~ > cat a.rb
class Fixnum
def to_bin
packed = [self].pack 'N'
n_bytes = packed.size
n_bits = n_bytes * 8
s = ''
n_bits.times{|bit| s << self[n_bits - bit].to_s}
s
end
end

p 42.to_bin
p -7.to_bin

harp:~ > ruby a.rb
"00000000000000000000000000010101"
"11111111111111111111111111111100"

but perhaps only printf will suffice?

irb(main):003:0> printf "%32.32b", -7
11111111111111111111111111111001=> nil

irb(main):009:0> printf "%4.4o", -7
7771=> nil

but i'm not exactly sure where you are headed with this.

the '...' above is just showing you the extension of the sign bit.

-a
--
================================================== =============================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| A flower falls, even though we love it;
| and a weed grows, even though we do not love it.
| --Dogen
================================================== =============================
 
Reply With Quote
 
Markus
Guest
Posts: n/a
 
      09-22-2004
On Wed, 2004-09-22 at 11:14, Paul wrote:
> Im trying to take a negative integer value, convert it to its binary
> equivalent, and save its hex value


So, are you wanting it in binary or in hex?

Assuming (from your context) that you're wanting it in hexadecimal
(base 16) instead of binary (base 2) you could write:

(a & 0xff).to_s(16)

for one byte values,

(a & 0xffff).to_s(16)

for two byte values, etc.

If you are wanting it in binary you would instead write:

(a & 0xff).to_s(2)

> How do I do what Im trying to do - given my -7 in the example may be a
> 1 byte, 2 byte or 4 byte value.


If you don't know at code-time how large the value will be, but can
determine it at run-time, you could write:

(a & (((1 << (8*n)) - 1)).to_s(16)

where n is the number of bytes in a and the expression involving a makes
a mask if the proper size. Alternatively, you could mess with the
result instead, by writing:

("0"*8 + (a & 0xffffffff).to_s(16))[-n*2..-1]

which pads the result with zeros and then takes the least significant 2n
hexits (i.e, the bottom n bytes).

-- Markus





 
Reply With Quote
 
Mark Hubbart
Guest
Posts: n/a
 
      09-22-2004

On Sep 22, 2004, at 11:14 AM, Paul wrote:

> Im trying to take a negative integer value, convert it to its binary
> equivalent, and save its hex value
>
> -7 -> 1111 1001 -> F9
>
>
> I was hoping to use sprintf, but:
>
> irb(main):017:0> b = sprintf("%4b" , a)
> => "..1001"
> irb(main):018:0>
>
> The .. that appear break any further processing. So my questions are:
>
> Why the dots, and what are they?
>
> How do I do what Im trying to do - given my -7 in the example may be a
> 1 byte, 2 byte or 4 byte value. ( Im sure its some magic with
> pack....)


well, if all you need is the hex part, here you go:

class Integer
def internal_hex
# choose a packing strategy
case self
when (-128..127) # char
[self].pack('c').unpack('C').first.to_s 16
when (-32768..32767) # short
[self].pack('s').unpack('S').first.to_s 16
when (-2147483648..2147483647) # long
[self].pack('l').unpack('L').first.to_s 16
else
"too big!" #
end
end
end

-7.internal_hex #=>"f9"


the hex string will be in big-endian (network) byte-order; that's the
way to_s(16) does it.

cheers
Mark


>
> Thanks
>
> Paul
>




 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      09-23-2004

<(E-Mail Removed)> schrieb im Newsbeitrag
news(E-Mail Removed) aa.gov...

> but perhaps only printf will suffice?
>
> irb(main):003:0> printf "%32.32b", -7
> 11111111111111111111111111111001=> nil


Hm...

10:25:20 [source]: irb
irb(main):001:0> printf "%32.32b", -7
00000000000000000000000000001001=> nil
irb(main):002:0> RUBY_VERSION
=> "1.8.1"

robert

 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      09-23-2004

"Florian Gross" <(E-Mail Removed)> schrieb im Newsbeitrag
news:(E-Mail Removed)...
> Paul wrote:
>
> Moin!
>
> > Im trying to take a negative integer value, convert it to its binary
> > equivalent, and save its hex value
> >
> > -7 -> 1111 1001 -> F9

>
> Does this help?
>
> irb(main):032:0> [-7].pack("c").unpack("H*").first
> => "f9"


That's nice although it is somewhat limited regarding the size of values:

>> [-7000].pack("c").unpack("H*").first

=> "a8"

After a bit experimenting I came up with this:

>> [-7].pack("i").unpack("h*").shift.reverse.gsub(/^f+(?=f)/, '')

=> "f9"
>> [-7000000].pack("i").unpack("h*").shift.reverse.gsub(/^f+(?=f)/, '')

=> "f953040"

Florian, what do you think?

Kind regards

robert

 
Reply With Quote
 
Florian Gross
Guest
Posts: n/a
 
      09-23-2004
Robert Klemme wrote:

> After a bit experimenting I came up with this:
>>>[-7].pack("i").unpack("h*").shift.reverse.gsub(/^f+(?=f)/, '')

>
> => "f9"
>
>>>[-7000000].pack("i").unpack("h*").shift.reverse.gsub(/^f+(?=f)/, '')

>
> => "f953040"
>
> Florian, what do you think?


Very nice, thank you. I wasn't aware of the range limit at first. Only
thing I would change is using .first instead of .shift. (For clarity)

> Kind regards
> robert


More regards,
Florian Gross
 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      09-23-2004

"Florian Gross" <(E-Mail Removed)> schrieb im Newsbeitrag
news:(E-Mail Removed)...
> Robert Klemme wrote:
>
> > After a bit experimenting I came up with this:
> >>>[-7].pack("i").unpack("h*").shift.reverse.gsub(/^f+(?=f)/, '')

> >
> > => "f9"
> >
> >>>[-7000000].pack("i").unpack("h*").shift.reverse.gsub(/^f+(?=f)/, '')

> >
> > => "f953040"
> >
> > Florian, what do you think?

>
> Very nice, thank you. I wasn't aware of the range limit at first. Only
> thing I would change is using .first instead of .shift. (For clarity)


) I deliberately choose #shift in order to make the array a bit
smaller and remove all unnecessary references to the string - kind of GC
paranoid.

Regards

robert

 
Reply With Quote
 
Markus
Guest
Posts: n/a
 
      09-23-2004
> > >>>[-7000000].pack("i").unpack("h*").shift.reverse.gsub(/^f+(?=f)/, '')

> > Very nice, thank you. I wasn't aware of the range limit at first. Only
> > thing I would change is using .first instead of .shift. (For clarity)

>
> ) I deliberately choose #shift in order to make the array a bit
> smaller and remove all unnecessary references to the string - kind of GC
> paranoid.


But:
1. the array can't be referenced after the first/shift returns
(since it was an anonymous link in a message chain), so the
whole array is subject to GC from that point
2. shift can be significantly slower than first
3. how do you know that shift isn't doing something like:

def Array.shift
result = @hypothetical_primitive_array[0]
@hypothetical_primitive_array = @hypothetical_primitive_array[1..-1]
result
end

...in which case you'd still have the (scavengable) copy around
just as if you'd done it yourself?

It only pays to be paranoid if you can trust yourself more than you can
trust "them".

-- Markus




 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Is MKV formats better than other video formats? helena68 Software 3 11-26-2008 07:57 AM
Detailed Analysis of the file formats for M$ Office 2007 -"Microsoft Office XML Formats? Defective by design" Jonathan Walker NZ Computing 1 08-26-2007 03:43 AM
CyberLink Supports UDF 2.5/2.6 Formats For Blu-ray and HD DVD next generation of disc formats. Allan DVD Video 0 07-15-2005 07:43 PM
Negative setup and Negative hold prem_eda VHDL 5 10-11-2004 12:14 PM
negative numbers and integer division Matthew Wilson Python 7 10-03-2003 09:53 PM



Advertisments