w wg wrote:

> Hi

> I' m using unpack to convert 4 bytes to local integer, but ruby just

> supply the "N" modifer which means unsigned long integer.

>

> My questions is :

> How to unpack 4 bytes to a signed integer ?
The best way I've found is to unpack with N (to get the swapping right)

and then do some arithmetic to interpret the unsigned value as signed:

x = -123

s = [x].pack("N")

# Note that for _pack_ there is no need for a

# special signed version of N

p s # ==> "\377\377\377\205"

length = 32

mid = 2**(length-1)

max_unsigned = 2**length

to_signed = proc {|n| (n>=mid) ? n - max_unsigned : n}

p to_signed[s.unpack("N").first] # ==> -123

This is all very hard for me to remember, so I've written a library to

do it, bit-struct (

http://redshift.sourceforge.net/bit-struct). This

makes life easier:

require 'bit-struct'

class Packet < BitStruct

signed

, 32

end

pkt = Packet.new

pkt.x = -123

p pkt.to_s # ==> "\377\377\377\205"

p pkt.x # ==> -123

# given string data from a network:

pkt2 = Packet.new("\377\377\377\205")

p pkt2.x # ==> -123

--

vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407