FUDforum - خوراک RDF
http://fudforum.org/forum/index.php
signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184577&th=123359#msg_184577
I'm having a bit of trouble figuring out a straightforward way to "pack" / "unpack" a signed int64.
I'm on a 64-bit machine, but the 'i' and 'I' are coming back with 4-byte length. And of course even though double comes back with 8 length it's a floating point and thus loses precision.
Any thoughts? Any help would be greatly appreciated.
BTW, unsigned int64 seems relatively straightforward, but signed int64 has been unusually difficult to figure out.
Thanks]]>cameron72014-01-12T02:18:34-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184578&th=123359#msg_184578
cameron7@gmail.com wrote:
> Hi,
>
> I'm having a bit of trouble figuring out a straightforward way to "pack" / "unpack" a signed int64.
>
> I'm on a 64-bit machine, but the 'i' and 'I' are coming back with 4-byte length. And of course even though double comes back with 8 length it's a floating point and thus loses precision.
>
> Any thoughts? Any help would be greatly appreciated.
>
> BTW, unsigned int64 seems relatively straightforward, but signed int64 has been unusually difficult to figure out.
>
> Thanks
>
You're on a 64 bit machine, but are you using a 64 bit OS and 64 bit PHP?
As for thoughts - how about some detail? What's you code? What do you
expect? What do you get?
--
==================
Remove the "x" from my email address
Jerry Stuckle jstucklex@attglobal.net
==================]]>Jerry Stuckle2014-01-12T02:35:02-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184579&th=123359#msg_184579
cameron7@gmail.com writes:
> I'm having a bit of trouble figuring out a straightforward way to
> "pack" / "unpack" a signed int64.
>
> I'm on a 64-bit machine, but the 'i' and 'I' are coming back with
> 4-byte length.
There is no explicit format for 64-bit ints. The i/I formats are used
for a native "int" but that need not be 64 bits on a 64-bit machine.
The function is borrowed from Perl whose documentation says a bit more
This 'integer' is _at_least_ 32 bits wide. Its exact size depends on
what a local C compiler calls 'int'.
On my 64-bit Linux machine, 'int' is 32 bits.
> And of course even though double comes back with 8
> length it's a floating point and thus loses precision.
>
> Any thoughts? Any help would be greatly appreciated.
You could, perhaps, just pack the two halves. Of course doing it
yourself rather defeats the purpose, but I am not sure there is another
way.
Depending on what you need this for, you could consider another format
altogether (ASCII, for example).
> BTW, unsigned int64 seems relatively straightforward, but signed int64
> has been unusually difficult to figure out.
How are you doing unsigned 64-bit ints?
--
Ben.]]>Ben Bacarisse2014-01-12T02:42:21-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184580&th=123359#msg_184580
Specifics from `php -i`: PHP Version => 5.4.6-1ubuntu1.5
The code has become extremely ugly, and still not working perfectly, thus the reason for trying to find others who may have experience with this. The pack / unpack functions don't provide support for 64-bit integers directly so I'm looking for at least a sound "hack".
I've tried all sorts of things, from base_convert to simply trying to extract and iterate over a bitwise comparison against each bit in 4 separate 16-bit ints, but nothing I've tried so far is working correctly.
Basically, the context for this is I'm writing a client for a custom protocol in which several of the components of that protocol in requests and responses require big endian 64-bit signed int, thus the reason for the need to pack / unpack.]]>cameron72014-01-12T02:46:34-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184581&th=123359#msg_184581
cameron7@gmail.com wrote:
> Hi, yes, sorry I am running 64-bit OS and 64-bit PHP. PHP_INT_MAX is
> giving appropriate value.
>
> Specifics from `php -i`: PHP Version => 5.4.6-1ubuntu1.5
>
> The code has become extremely ugly, and still not working perfectly,
> thus the reason for trying to find others who may have experience
> with this. The pack / unpack functions don't provide support for
> 64-bit integers directly so I'm looking for at least a sound "hack".
>
> I've tried all sorts of things, from base_convert to simply trying to
> extract and iterate over a bitwise comparison against each bit in 4
> separate 16-bit ints, but nothing I've tried so far is working
> correctly.
>
> Basically, the context for this is I'm writing a client for a custom
> protocol in which several of the components of that protocol in
> requests and responses require big endian 64-bit signed int, thus the
> reason for the need to pack / unpack.
>
I have to say this is where I would probably be trying to write a C
library and wrap it in PHP..
Or write a C daemon and interrogate that..via a named pipe or system
type call.
This is system level programming and PHP is simply not the right tool
for it.
--
Ineptocracy
(in-ep-toc’-ra-cy) – a system of government where the least capable to
lead are elected by the least capable of producing, and where the
members of society least likely to sustain themselves or succeed, are
rewarded with goods and services paid for by the confiscated wealth of a
diminishing number of producers.]]>The Natural Philosoph2014-01-12T02:59:59-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184583&th=123359#msg_184583
> cameron7@gmail.com writes:
>
>> I'm having a bit of trouble figuring out a straightforward way to
>> "pack" / "unpack" a signed int64.
>>
>> I'm on a 64-bit machine, but the 'i' and 'I' are coming back with
>> 4-byte length.
>
> There is no explicit format for 64-bit ints. The i/I formats are used
> for a native "int" but that need not be 64 bits on a 64-bit machine.
> The function is borrowed from Perl whose documentation says a bit more
>
> This 'integer' is _at_least_ 32 bits wide. Its exact size depends on
> what a local C compiler calls 'int'.
>
> On my 64-bit Linux machine, 'int' is 32 bits.
>
On my 64 bit Linux system, 'int' is 64 bits. But then I have the 64 bit
PHP version (and 64 bit OS) loaded.
What do you get when you do:
<?php
echo PHP_INT_MAX . "\n";
?>
--
==================
Remove the "x" from my email address
Jerry Stuckle jstucklex@attglobal.net
==================]]>Jerry Stuckle2014-01-12T03:01:24-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184584&th=123359#msg_184584
> On 12/01/14 02:46, cameron7@gmail.com wrote:
>> Hi, yes, sorry I am running 64-bit OS and 64-bit PHP. PHP_INT_MAX is
>> giving appropriate value.
>>
>> Specifics from `php -i`: PHP Version => 5.4.6-1ubuntu1.5
>>
>> The code has become extremely ugly, and still not working perfectly,
>> thus the reason for trying to find others who may have experience
>> with this. The pack / unpack functions don't provide support for
>> 64-bit integers directly so I'm looking for at least a sound "hack".
>>
>> I've tried all sorts of things, from base_convert to simply trying to
>> extract and iterate over a bitwise comparison against each bit in 4
>> separate 16-bit ints, but nothing I've tried so far is working
>> correctly.
>>
>> Basically, the context for this is I'm writing a client for a custom
>> protocol in which several of the components of that protocol in
>> requests and responses require big endian 64-bit signed int, thus the
>> reason for the need to pack / unpack.
>>
>
> I have to say this is where I would probably be trying to write a C
> library and wrap it in PHP..
>
> Or write a C daemon and interrogate that..via a named pipe or system
> type call.
>
> This is system level programming and PHP is simply not the right tool
> for it.
>
>
>
>
>
You'd write a 5,000 line C program to say "Hello, World".
--
==================
Remove the "x" from my email address
Jerry Stuckle jstucklex@attglobal.net
==================]]>Jerry Stuckle2014-01-12T03:03:57-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184585&th=123359#msg_184585
cameron7@gmail.com wrote:
> Hi, yes, sorry I am running 64-bit OS and 64-bit PHP. PHP_INT_MAX is giving appropriate value.
>
> Specifics from `php -i`: PHP Version => 5.4.6-1ubuntu1.5
>
> The code has become extremely ugly, and still not working perfectly, thus the reason for trying to find others who may have experience with this. The pack / unpack functions don't provide support for 64-bit integers directly so I'm looking for at least a sound "hack".
>
> I've tried all sorts of things, from base_convert to simply trying to extract and iterate over a bitwise comparison against each bit in 4 separate 16-bit ints, but nothing I've tried so far is working correctly.
>
> Basically, the context for this is I'm writing a client for a custom protocol in which several of the components of that protocol in requests and responses require big endian 64-bit signed int, thus the reason for the need to pack / unpack.
>
That may be, but without knowing exactly what you're doing and what you
expect, any attempt to help you would be a waste of both your and our time.
--
==================
Remove the "x" from my email address
Jerry Stuckle jstucklex@attglobal.net
==================]]>Jerry Stuckle2014-01-12T03:04:50-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184586&th=123359#msg_184586
I'm working up a more digestible summary should be back later this evening.]]>cameron72014-01-12T03:08:39-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184587&th=123359#msg_184587
cameron72014-01-12T03:10:20-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184588&th=123359#msg_184588
jstucklex@attglobal.net> writes:
> On 1/11/2014 9:42 PM, Ben Bacarisse wrote:
>> cameron7@gmail.com writes:
>>
>>> I'm having a bit of trouble figuring out a straightforward way to
>>> "pack" / "unpack" a signed int64.
>>>
>>> I'm on a 64-bit machine, but the 'i' and 'I' are coming back with
>>> 4-byte length.
>>
>> There is no explicit format for 64-bit ints. The i/I formats are used
>> for a native "int" but that need not be 64 bits on a 64-bit machine.
>> The function is borrowed from Perl whose documentation says a bit more
>>
>> This 'integer' is _at_least_ 32 bits wide. Its exact size depends on
>> what a local C compiler calls 'int'.
^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> On my 64-bit Linux machine, 'int' is 32 bits.
>
> On my 64 bit Linux system, 'int' is 64 bits. But then I have the 64
> bit PHP version (and 64 bit OS) loaded.
Yes, me too.
> What do you get when you do:
>
> <?php
> echo PHP_INT_MAX . "\n";
> ?>
Same as you but I don't think that's relevant. PHP stores values
internally using a C long. I think the Perl document describes what's
really happening.
--
Ben.]]>Ben Bacarisse2014-01-12T03:11:27-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184589&th=123359#msg_184589
> Jerry Stuckle <jstucklex@attglobal.net> writes:
>
>> On 1/11/2014 9:42 PM, Ben Bacarisse wrote:
>>> cameron7@gmail.com writes:
>>>
>>>> I'm having a bit of trouble figuring out a straightforward way to
>>>> "pack" / "unpack" a signed int64.
>>>>
>>>> I'm on a 64-bit machine, but the 'i' and 'I' are coming back with
>>>> 4-byte length.
>>>
>>> There is no explicit format for 64-bit ints. The i/I formats are used
>>> for a native "int" but that need not be 64 bits on a 64-bit machine.
>>> The function is borrowed from Perl whose documentation says a bit more
>>>
>>> This 'integer' is _at_least_ 32 bits wide. Its exact size depends on
>>> what a local C compiler calls 'int'.
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>> On my 64-bit Linux machine, 'int' is 32 bits.
>>
>> On my 64 bit Linux system, 'int' is 64 bits. But then I have the 64
>> bit PHP version (and 64 bit OS) loaded.
>
> Yes, me too.
>
>> What do you get when you do:
>>
>> <?php
>> echo PHP_INT_MAX . "\n";
>> ?>
>
> Same as you but I don't think that's relevant. PHP stores values
> internally using a C long. I think the Perl document describes what's
> really happening.
>
It is totally relevant. You can't operate on 64 bit values if you don't
have 64 bit support.
And this is PHP, not Perl. Things have changed a *lot* since the
original versions were created. Much of the Perl documentation no
longer applies to PHP (if it ever did).
--
==================
Remove the "x" from my email address
Jerry Stuckle jstucklex@attglobal.net
==================]]>Jerry Stuckle2014-01-12T03:15:01-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184590&th=123359#msg_184590
This is giving me:
This likely will simply require some experimentation, for example I'm using "unsigned" flags to unpack, but it's not obvious, since when I go with a "signed" flag for negative values (ie. 'l' for signed long) I'm getting the same. If someone on the list has experience hacking binary protocols in PHP would love to know if there's a better way...
> On 1/11/2014 10:11 PM, Ben Bacarisse wrote:
>> Jerry Stuckle <jstucklex@attglobal.net> writes:
>>
>>> On 1/11/2014 9:42 PM, Ben Bacarisse wrote:
>>>> cameron7@gmail.com writes:
>>>>
>>>> > I'm having a bit of trouble figuring out a straightforward way to
>>>> > "pack" / "unpack" a signed int64.
>>>> >
>>>> > I'm on a 64-bit machine, but the 'i' and 'I' are coming back with
>>>> > 4-byte length.
>>>>
>>>> There is no explicit format for 64-bit ints. The i/I formats are used
>>>> for a native "int" but that need not be 64 bits on a 64-bit machine.
>>>> The function is borrowed from Perl whose documentation says a bit more
>>>>
>>>> This 'integer' is _at_least_ 32 bits wide. Its exact size depends on
>>>> what a local C compiler calls 'int'.
>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>>> On my 64-bit Linux machine, 'int' is 32 bits.
>>>
>>> On my 64 bit Linux system, 'int' is 64 bits. But then I have the 64
>>> bit PHP version (and 64 bit OS) loaded.
>>
>> Yes, me too.
>>
>>> What do you get when you do:
>>>
>>> <?php
>>> echo PHP_INT_MAX . "\n";
>>> ?>
>>
>> Same as you but I don't think that's relevant. PHP stores values
>> internally using a C long. I think the Perl document describes what's
>> really happening.
>
> It is totally relevant. You can't operate on 64 bit values if you
> don't have 64 bit support.
The Perl documentation seems to describe what's happening. The PHP
documentation leaves the nature of the integer of "machine dependent
size" unspecified so some clarification is helpful.
64 bit support may be necessary but it seems not to be sufficient. Many
64 systems leave C's "int" as 32 bits, so if pack is still doing what
the Perl version describes, it's at least an explanation of what's
happening.
> And this is PHP, not Perl. Things have changed a *lot* since the
> original versions were created. Much of the Perl documentation no
> longer applies to PHP (if it ever did).
I am sure that's true, but, other than the source, I don't think there
is much more to go on. What is your explanation of what's going on?
--
Ben.]]>Ben Bacarisse2014-01-12T12:37:53-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184593&th=123359#msg_184593
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 :)
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));
}]]>cameron72014-01-12T15:25:31-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184594&th=123359#msg_184594
> Jerry Stuckle <jstucklex@attglobal.net> writes:
>
>> On 1/11/2014 10:11 PM, Ben Bacarisse wrote:
>>> Jerry Stuckle <jstucklex@attglobal.net> writes:
>>>
>>>> On 1/11/2014 9:42 PM, Ben Bacarisse wrote:
>>>> > cameron7@gmail.com writes:
>>>> >
>>>> >> I'm having a bit of trouble figuring out a straightforward way to
>>>> >> "pack" / "unpack" a signed int64.
>>>> >>
>>>> >> I'm on a 64-bit machine, but the 'i' and 'I' are coming back with
>>>> >> 4-byte length.
>>>> >
>>>> > There is no explicit format for 64-bit ints. The i/I formats are used
>>>> > for a native "int" but that need not be 64 bits on a 64-bit machine.
>>>> > The function is borrowed from Perl whose documentation says a bit more
>>>> >
>>>> > This 'integer' is _at_least_ 32 bits wide. Its exact size depends on
>>>> > what a local C compiler calls 'int'.
>>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>>> > On my 64-bit Linux machine, 'int' is 32 bits.
>>>>
>>>> On my 64 bit Linux system, 'int' is 64 bits. But then I have the 64
>>>> bit PHP version (and 64 bit OS) loaded.
>>>
>>> Yes, me too.
>>>
>>>> What do you get when you do:
>>>>
>>>> <?php
>>>> echo PHP_INT_MAX . "\n";
>>>> ?>
>>>
>>> Same as you but I don't think that's relevant. PHP stores values
>>> internally using a C long. I think the Perl document describes what's
>>> really happening.
>>
>> It is totally relevant. You can't operate on 64 bit values if you
>> don't have 64 bit support.
>
> The Perl documentation seems to describe what's happening. The PHP
> documentation leaves the nature of the integer of "machine dependent
> size" unspecified so some clarification is helpful.
>
> 64 bit support may be necessary but it seems not to be sufficient. Many
> 64 systems leave C's "int" as 32 bits, so if pack is still doing what
> the Perl version describes, it's at least an explanation of what's
> happening.
>
>> And this is PHP, not Perl. Things have changed a *lot* since the
>> original versions were created. Much of the Perl documentation no
>> longer applies to PHP (if it ever did).
>
> I am sure that's true, but, other than the source, I don't think there
> is much more to go on. What is your explanation of what's going on?
>
You can argue, or you can answer our questions and get help.
I see you've already got the answers and all you want to do is argue.
Sorry I wasted my time and the network's bandwidth trying to help you.
--
==================
Remove the "x" from my email address
Jerry Stuckle jstucklex@attglobal.net
==================]]>Jerry Stuckle2014-01-12T15:51:05-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184595&th=123359#msg_184595
> On 1/12/2014 7:37 AM, Ben Bacarisse wrote:
>> Jerry Stuckle <jstucklex@attglobal.net> writes:
>>
>>> On 1/11/2014 10:11 PM, Ben Bacarisse wrote:
>>>> Jerry Stuckle <jstucklex@attglobal.net> writes:
>>>>
>>>> > On 1/11/2014 9:42 PM, Ben Bacarisse wrote:
>>>> >> cameron7@gmail.com writes:
>>>> >>
>>>> >>> I'm having a bit of trouble figuring out a straightforward way to
>>>> >>> "pack" / "unpack" a signed int64.
>>>> >>>
>>>> >>> I'm on a 64-bit machine, but the 'i' and 'I' are coming back with
>>>> >>> 4-byte length.
>>>> >>
>>>> >> There is no explicit format for 64-bit ints. The i/I formats are
>>>> >> used
>>>> >> for a native "int" but that need not be 64 bits on a 64-bit machine.
>>>> >> The function is borrowed from Perl whose documentation says a bit
>>>> >> more
>>>> >>
>>>> >> This 'integer' is _at_least_ 32 bits wide. Its exact size
>>>> >> depends on
>>>> >> what a local C compiler calls 'int'.
>>>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>>> >> On my 64-bit Linux machine, 'int' is 32 bits.
>>>> >
>>>> > On my 64 bit Linux system, 'int' is 64 bits. But then I have the 64
>>>> > bit PHP version (and 64 bit OS) loaded.
>>>>
>>>> Yes, me too.
>>>>
>>>> > What do you get when you do:
>>>> >
>>>> > <?php
>>>> > echo PHP_INT_MAX . "\n";
>>>> > ?>
>>>>
>>>> Same as you but I don't think that's relevant. PHP stores values
>>>> internally using a C long. I think the Perl document describes what's
>>>> really happening.
>>>
>>> It is totally relevant. You can't operate on 64 bit values if you
>>> don't have 64 bit support.
>>
>> The Perl documentation seems to describe what's happening. The PHP
>> documentation leaves the nature of the integer of "machine dependent
>> size" unspecified so some clarification is helpful.
>>
>> 64 bit support may be necessary but it seems not to be sufficient. Many
>> 64 systems leave C's "int" as 32 bits, so if pack is still doing what
>> the Perl version describes, it's at least an explanation of what's
>> happening.
>>
>>> And this is PHP, not Perl. Things have changed a *lot* since the
>>> original versions were created. Much of the Perl documentation no
>>> longer applies to PHP (if it ever did).
>>
>> I am sure that's true, but, other than the source, I don't think there
>> is much more to go on. What is your explanation of what's going on?
>>
>
> You can argue, or you can answer our questions and get help.
>
> I see you've already got the answers and all you want to do is argue.
> Sorry I wasted my time and the network's bandwidth trying to help you.
Jerry, please note that Ben, to whom you've replied, is not the OP. :)
--
Christoph M. Becker]]>Christoph Michael Bec2014-01-12T16:00:01-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184596&th=123359#msg_184596
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.
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
==================]]>Jerry Stuckle2014-01-12T16:11:20-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184598&th=123359#msg_184598
cameron7@gmail.com wrote:
> I'm having a bit of trouble figuring out a straightforward way to
> "pack" / "unpack" a signed int64.
>
> I'm on a 64-bit machine, but the 'i' and 'I' are coming back with
> 4-byte length. And of course even though double comes back with 8
> length it's a floating point and thus loses precision.
>
> Any thoughts? Any help would be greatly appreciated.
>
> BTW, unsigned int64 seems relatively straightforward, but signed
> int64 has been unusually difficult to figure out.
It seems to me that it should be possible to pack 64bit numbers by
splitting them into two 32bit numbers and packing the "halves", as Ben
already noticed. Unpacking should be possible by doing the reverse
operations. It shouldn't really matter in this case if you're dealing
with signed or unsigned values, if your platform supports the respective
64bit values.
I can't test with 64bit Integers as I'm on Windows with
PHP_INT_MAX==2147483647. However, I've written the following functions
for working with 32bit integers by relying on the 'n' format of
pack()/unpack(). You may try to adjust the functions for 64bit by using
the 'N' format and replacing the literal "16" with "32".
--
Christoph M. Becker]]>Christoph Michael Bec2014-01-12T16:37:49-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184608&th=123359#msg_184608
> Jerry Stuckle wrote:
>
>> On 1/12/2014 7:37 AM, Ben Bacarisse wrote:
>>> Jerry Stuckle <jstucklex@attglobal.net> writes:
>>>
>>>> On 1/11/2014 10:11 PM, Ben Bacarisse wrote:
>>>> > Jerry Stuckle <jstucklex@attglobal.net> writes:
>>>> >
>>>> >> On 1/11/2014 9:42 PM, Ben Bacarisse wrote:
>>>> >>> cameron7@gmail.com writes:
>>>> >>>
>>>> >>>> I'm having a bit of trouble figuring out a straightforward way to
>>>> >>>> "pack" / "unpack" a signed int64.
>>>> >>>>
>>>> >>>> I'm on a 64-bit machine, but the 'i' and 'I' are coming back with
>>>> >>>> 4-byte length.
>>>> >>>
>>>> >>> There is no explicit format for 64-bit ints. The i/I formats are
>>>> >>> used
>>>> >>> for a native "int" but that need not be 64 bits on a 64-bit machine.
>>>> >>> The function is borrowed from Perl whose documentation says a bit
>>>> >>> more
>>>> >>>
>>>> >>> This 'integer' is _at_least_ 32 bits wide. Its exact size
>>>> >>> depends on
>>>> >>> what a local C compiler calls 'int'.
>>>> > ^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>>> >>> On my 64-bit Linux machine, 'int' is 32 bits.
>>>> >>
>>>> >> On my 64 bit Linux system, 'int' is 64 bits. But then I have the 64
>>>> >> bit PHP version (and 64 bit OS) loaded.
>>>> >
>>>> > Yes, me too.
>>>> >
>>>> >> What do you get when you do:
>>>> >>
>>>> >> <?php
>>>> >> echo PHP_INT_MAX . "\n";
>>>> >> ?>
>>>> >
>>>> > Same as you but I don't think that's relevant. PHP stores values
>>>> > internally using a C long. I think the Perl document describes what's
>>>> > really happening.
>>>>
>>>> It is totally relevant. You can't operate on 64 bit values if you
>>>> don't have 64 bit support.
>>>
>>> The Perl documentation seems to describe what's happening. The PHP
>>> documentation leaves the nature of the integer of "machine dependent
>>> size" unspecified so some clarification is helpful.
>>>
>>> 64 bit support may be necessary but it seems not to be sufficient. Many
>>> 64 systems leave C's "int" as 32 bits, so if pack is still doing what
>>> the Perl version describes, it's at least an explanation of what's
>>> happening.
>>>
>>>> And this is PHP, not Perl. Things have changed a *lot* since the
>>>> original versions were created. Much of the Perl documentation no
>>>> longer applies to PHP (if it ever did).
>>>
>>> I am sure that's true, but, other than the source, I don't think there
>>> is much more to go on. What is your explanation of what's going on?
>>>
>>
>> You can argue, or you can answer our questions and get help.
>>
>> I see you've already got the answers and all you want to do is argue.
>> Sorry I wasted my time and the network's bandwidth trying to help you.
>
> Jerry, please note that Ben, to whom you've replied, is not the OP. :)
>
Yes, I know. But he keeps referring to information that is > 15 years
old. PHP has changed a lot since then, but we just wants to argue.
--
==================
Remove the "x" from my email address
Jerry Stuckle jstucklex@attglobal.net
==================]]>Jerry Stuckle2014-01-12T21:09:39-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184609&th=123359#msg_184609
jstucklex@attglobal.net> writes:
<snip>
> You can argue, or you can answer our questions and get help.
What questions didn't I answer? Who is included in "our"?
As best I can tell you asked me one (which I answered) and I don't think
anyone else as has asked me any.
> I see you've already got the answers and all you want to do is
> argue. Sorry I wasted my time and the network's bandwidth trying to
> help you.
Have I done something to make you angry? We were having what I though
was civil exchange about a technical matter, and then this.
--
Ben.]]>Ben Bacarisse2014-01-12T22:30:25-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184610&th=123359#msg_184610
jstucklex@attglobal.net> writes:
<snip>
> Yes, I know. But he keeps referring to information that is > 15 years
> old. PHP has changed a lot since then, but we just wants to argue.
Old information can be accurate. I don't know if it is in this case,
but it explains the OP's results better than the more recent PHP
documentation does. When I asked you your opinion of what's happening,
you went all angry and weird.
--
Ben.]]>Ben Bacarisse2014-01-12T22:35:25-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184612&th=123359#msg_184612
> Jerry Stuckle <jstucklex@attglobal.net> writes:
> <snip>
>> Yes, I know. But he keeps referring to information that is > 15 years
>> old. PHP has changed a lot since then, but we just wants to argue.
>
> Old information can be accurate. I don't know if it is in this case,
> but it explains the OP's results better than the more recent PHP
> documentation does. When I asked you your opinion of what's happening,
> you went all angry and weird.
>
Exactly. You don't know if the information is accurate. Yet you
continue to argue about it.
And more recent PHP documentation is more accurate because it relates to
the CURRENT code base, not one that is over 15 years old.
As for getting "angry and weird" - maybe I'm just tired of arguing with
people who base their position on old and/or inaccurate information (or
translation thereof), and refuse to look at any other possibility.
--
==================
Remove the "x" from my email address
Jerry Stuckle jstucklex@attglobal.net
==================]]>Jerry Stuckle2014-01-12T22:59:36-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184615&th=123359#msg_184615
cameron7@gmail.com writes:
> I guess I'll reply with my own solution. Turns out there are 2
> separate issues here.
Here's mine. You might have to alter the order of the two 32-bit
components to match your external format. I've used the same names you
might be able to drop it into your tests.
--
Ben.]]>Ben Bacarisse2014-01-12T23:27:04-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184616&th=123359#msg_184616
cameron72014-01-13T00:03:53-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184617&th=123359#msg_184617
For another day I guess...]]>cameron72014-01-13T00:22:26-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184618&th=123359#msg_184618
cameron7@gmail.com writes:
> Although it does lead me to the question, how will we do unsigned
> int64 :)
:) indeed! PHP does not support unsigned integers so it's a genuine
problem. In languages without unsigned integers, you can get by only
when the larges unsigned quantity you every use is <= INT_MAX.
> For another day I guess...
The answer will depend on what the code must do with the results.
Keeping them as signed might work for a lot of what gets done with it.
--
Ben.]]>Ben Bacarisse2014-01-13T01:20:28-00:00Re: signed int64 pack/unpack
http://fudforum.org/forum/index.phpindex.php?t=rview&goto=184621&th=123359#msg_184621
jstucklex@attglobal.net> writes:
> On 1/12/2014 5:35 PM, Ben Bacarisse wrote:
>> Jerry Stuckle <jstucklex@attglobal.net> writes:
>> <snip>
>>> Yes, I know. But he keeps referring to information that is > 15 years
>>> old. PHP has changed a lot since then, but we just wants to argue.
>>
>> Old information can be accurate. I don't know if it is in this case,
>> but it explains the OP's results better than the more recent PHP
>> documentation does. When I asked you your opinion of what's happening,
>> you went all angry and weird.
>>
>
> Exactly. You don't know if the information is accurate. Yet you
> continue to argue about it.
>
> And more recent PHP documentation is more accurate because it relates
> to the CURRENT code base, not one that is over 15 years old.
I could not find an explanation in the PHP documentation. I am sure it
is more up-to-date (and more applicable) but there was no answer there
that I could see.
As it happens, the current code base references Perl for the behaviour.
A comment at the start of pack.c says:
/* pack() idea stolen from Perl (implemented formats behave the same as there)
* Implemented formats are Z, A, a, h, H, c, C, s, S, i, I, l, L, n, N, f, d, x, X, @.
*/
So the code authors would have pointed me to Perl's pack function had I
not already gone there and, as documented, the code for the i and I are
based on the size of a C int (on the build system):
case 'i':
case 'I':
while (arg-- > 0) {
php_pack(argv[currentarg++], sizeof(int), int_map, &output[outputpos]);
outputpos += sizeof(int);
}
break;
> As for getting "angry and weird" - maybe I'm just tired of arguing
> with people who base their position on old and/or inaccurate
> information (or translation thereof), and refuse to look at any other
> possibility.
I am open to other possibilities. What is your opinion about what i and
I do and the size of integer they work with?. I didn't pretend to know
what is actually going on, just what seemed to be going on.