Mohanraj
Mohanraj

Reputation: 4200

How Ruby string unpack works for extracting 16, 32 and 64 signed/unsigned values?

Ruby unpacking 8-bit signed/unsigned char is basically returns decimal value of each byte(char) as an array,

'12'.unpack 'C*'
# => [49, 50]

So, I can understand the unpacking of 8-bit signed/unsigned char from a string. But how the 16, 32 and 64 bit signed/unsigned unpacking works?

'12'.unpack('S*')
# => [12849]
'1234'.unpack('L*')
# => [875770417]
'12345678'.unpack('Q*')
# => [4050765991979987505]

From the above output I can understand S, L and Q is picking bytes 2, 4 and 8 accordingly, but how the value is calculated?

Upvotes: 2

Views: 445

Answers (1)

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

It’s basically the number in 256 base, converted to Integer.

▶ '12'.unpack('S*') == [50 * 256 + 49]
#⇒ true

▶ '1234'.bytes
#⇒ [49, 50, 51, 52]
▶ '1234'.unpack('L*') ==
▷    [52 * 256 * 256 * 256 + 51 * 256 * 256 + 50 * 256 + 49]
#⇒ true

Please note, S, L and Q are platform dependent. To ensure little-endian, one might use (credits to @NeilSlater):

▶ '12'.unpack('S<*') == [50 * 256 + 49]
#⇒ true

For big-endian one might use > modifier:

▶ '12'.unpack('S>*') == [49 * 256 + 50]
#⇒ true

Upvotes: 4

Related Questions