Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.php > #12611
| From | Jerry Stuckle <jstucklex@attglobal.net> |
|---|---|
| Newsgroups | comp.lang.php |
| Subject | Re: signed int64 pack/unpack |
| Date | 2014-01-12 11:11 -0500 |
| Organization | A noiseless patient Spider |
| Message-ID | <lauer1$mff$1@dont-email.me> (permalink) |
| References | <13b7b4d5-1ae0-4e04-910b-112f9a1631cc@googlegroups.com> <0.27f2c8a43d10a3f72059.20140112024221GMT.87fvot3oqa.fsf@bsb.me.uk> <94a0c833-7c16-4afc-aab4-37e660229187@googlegroups.com> <6b352c09-6253-41c3-a879-44643778d66f@googlegroups.com> |
On 1/12/2014 10:25 AM, cameron7@gmail.com wrote:
> 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.
>
True. base_convert
> 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.
>
That's because when you use 2's compliment, you need to flip the bits
and add one.
>
> 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));
> }
>
I've seen worse :)
However, you might want to check some other functions. The gmp_xxx
functions will work on longer numbers; so will the BCD functions.
There are some suggestions and links under base_convert() in the online
documentation at http://us1.php.net/manual/en/function.base-convert.php.
Of course, if you're on a shared host and can't get them to install the
libraries for you, you're out of luck.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Back to comp.lang.php | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
signed int64 pack/unpack cameron7@gmail.com - 2014-01-11 18:18 -0800
Re: signed int64 pack/unpack Jerry Stuckle <jstucklex@attglobal.net> - 2014-01-11 21:35 -0500
Re: signed int64 pack/unpack cameron7@gmail.com - 2014-01-11 18:46 -0800
Re: signed int64 pack/unpack The Natural Philosopher <tnp@invalid.invalid> - 2014-01-12 02:59 +0000
Re: signed int64 pack/unpack Jerry Stuckle <jstucklex@attglobal.net> - 2014-01-11 22:03 -0500
Re: signed int64 pack/unpack cameron7@gmail.com - 2014-01-11 19:10 -0800
Re: signed int64 pack/unpack Jerry Stuckle <jstucklex@attglobal.net> - 2014-01-11 22:04 -0500
Re: signed int64 pack/unpack Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-01-12 02:42 +0000
Re: signed int64 pack/unpack Jerry Stuckle <jstucklex@attglobal.net> - 2014-01-11 22:01 -0500
Re: signed int64 pack/unpack cameron7@gmail.com - 2014-01-11 19:08 -0800
Re: signed int64 pack/unpack Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-01-12 03:11 +0000
Re: signed int64 pack/unpack Jerry Stuckle <jstucklex@attglobal.net> - 2014-01-11 22:15 -0500
Re: signed int64 pack/unpack Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-01-12 12:37 +0000
Re: signed int64 pack/unpack Jerry Stuckle <jstucklex@attglobal.net> - 2014-01-12 10:51 -0500
Re: signed int64 pack/unpack Christoph Michael Becker <cmbecker69@arcor.de> - 2014-01-12 17:00 +0100
Re: signed int64 pack/unpack Jerry Stuckle <jstucklex@attglobal.net> - 2014-01-12 16:09 -0500
Re: signed int64 pack/unpack Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-01-12 22:35 +0000
Re: signed int64 pack/unpack Jerry Stuckle <jstucklex@attglobal.net> - 2014-01-12 17:59 -0500
Re: signed int64 pack/unpack Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-01-13 01:59 +0000
Re: signed int64 pack/unpack Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-01-12 22:30 +0000
Re: signed int64 pack/unpack cameron7@gmail.com - 2014-01-11 21:54 -0800
Re: signed int64 pack/unpack cameron7@gmail.com - 2014-01-12 07:25 -0800
Re: signed int64 pack/unpack Jerry Stuckle <jstucklex@attglobal.net> - 2014-01-12 11:11 -0500
Re: signed int64 pack/unpack Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-01-12 23:27 +0000
Re: signed int64 pack/unpack cameron7@gmail.com - 2014-01-12 16:03 -0800
Re: signed int64 pack/unpack cameron7@gmail.com - 2014-01-12 16:22 -0800
Re: signed int64 pack/unpack Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-01-13 01:20 +0000
Re: signed int64 pack/unpack Christoph Michael Becker <cmbecker69@arcor.de> - 2014-01-12 17:37 +0100
csiph-web