FUDforum
Fast Uncompromising Discussions. FUDforum will get your users talking.

Home » Imported messages » comp.lang.php » signed int64 pack/unpack
Show: Today's Messages :: Polls :: Message Navigator
Return to the default flat view Create a new topic Submit Reply
Re: signed int64 pack/unpack [message #184593 is a reply to message #184590] Sun, 12 January 2014 15:25 Go to previous messageGo to previous message
cameron7 is currently offline  cameron7
Messages: 8
Registered: January 2014
Karma:
Junior Member
I guess I'll reply with my own solution. Turns out there are 2 separate issues here.

1) the "signed" bit needs to be flipped back to 0 before converting to int. This is because it appears the conversion from base 2 to base 10 will always assume the end value is positive.
2) Because of this, the rest of the bits need to be flipped.

So I added 2 arguments to the function, one will tell us if we're supposed to be checking for a "signed bit", and the other will tell us if we need to flip bits.

As you'll see I'm still off by 1 in the end result, but I'm sure that's just in the details.


I hope you'll all agree, this is really ugly, but seems to work :)

<?php

$i64 = -8223372036854775807;

echo "PACKING: ".$i64.PHP_EOL;

list(,$binary) = getBinaryString($i64, 64);

list(,$i64a) = unpack('N', pack('N', base_convert(substr($binary, 0, 32), 2, 10)));
list(,$i64b) = unpack('N', pack('N', base_convert(substr($binary, 32, 32), 2, 10)));

list($flag,$i64c)= getBinaryString($i64a, 32, true, true);
list(,$i64d) = getBinaryString($i64b, 32, false, true);

$unpack = base_convert($i64c.$i64d,2,10);
$unpack *= $flag ? -1 : 1;

echo "UNPACKED: ".$unpack.PHP_EOL;

function getBinaryString($packed,$bits,$check_signed = false, $flip = false){
$a = 0x01;
$binary = '';
for($x=0; $x<$bits; $x++){
$binary .= (int)(bool)($a & $packed);
$a = $a << 1;
}
$signed_flag = false;
if($check_signed && substr($binary,$bits-1,1) === '1'){
$signed_flag = true;
}
if($flip){
for($x=0;$x<strlen($binary);$x++){
$binary[$x] = $binary[$x] === '1' ? '0' : '1';
}
}
if($signed_flag){
$binary = substr($binary,0,$bits-1).'0';
}
return array($signed_flag, strrev($binary));
}
[Message index]
 
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Previous Topic: how did I wind up with double headers?
Next Topic: Switch question
Goto Forum:
  

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ]

Current Time: Fri Nov 22 02:11:01 GMT 2024

Total time taken to generate the page: 0.04253 seconds