in reply to 3-byte representation
If you want big-endian byte order:
pack: $s = substr(pack('l>', $n), 1);
unpack: $n = unpack('l>', "$s\0")/256;
If you want little-endian byte order:
pack: $s = substr(pack('l<', $n), 0, 3);
unpack: $n = unpack('l<', "\0$s")/256;
PS — Going from 3 to 4 increases the space needed by 33%, not 25%.
Update: Slightly simpler solutions.
Update: The /256 got dropped when I posted my solution. Fixed.
Re^2: 3-byte representation
by BrowserUk (Patriarch) on Oct 12, 2011 at 18:32 UTC
|
sub pack24{ substr( pack('l>', $_[0]), 1) };;
sub unpack24{ unpack('l>', "$_[0]\0") };;
print "$_: ", unpack24( pack24( $_ ) )
for ( -8388608, -8388607, -2, -1, 0, 1, 2, 8388606, 8388607 );;
-8388608: -2147483648
-8388607: -2147483392
-2: -512
-1: -256
0: 0
1: 256
2: 512
8388606: 2147483136
8388607: 2147483392
Little-endian: sub pack24{ substr( pack('l<', $_[0]), 1) };;
sub unpack24{ unpack('l<', "$_[0]\0") };;
print "$_: ", unpack24( pack24( $_ ) )
for ( -8388608, -8388607, -2, -1, 0, 1, 2, 8388606, 8388607 );;
-8388608: 16744448
-8388607: 16744448
-2: 16777215
-1: 16777215
0: 0
1: 0
2: 0
8388606: 32767
8388607: 32767
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |
|
| [reply] [d/l] |
Re^2: 3-byte representation
by BrowserUk (Patriarch) on Oct 12, 2011 at 19:10 UTC
|
I tested my solutions before posting them.
Really? Really, really? Hm?
#! perl -slw
use strict;
sub pack24be{ substr( pack('l>', $_[0]), 1) }
sub unpack24be{ unpack('l>', "$_[0]\0") >> 8 }
sub pack24le{ substr( pack('l<', $_[0] ), 0, 3); }
sub unpack24le{ unpack( 'l<', "\0$_[0]" ) >> 8 }
print( "be: $_: ", unpack24be( pack24be( $_ ) ) ),
print( "le: $_: ", unpack24le( pack24le( $_ ) ) )
for ( -8388608, -8388607, -2, -1, 0, 1, 2, 8388606, 8388607 )
__END__
C:\test>junk101 (version 2 )
be: -8388608: -2147483648
le: -8388608: -2147483648
be: -8388607: -2147483392
le: -8388607: -2147483392
be: -2: -512
le: -2: -512
be: -1: -256
le: -1: -256
be: 0: 0
le: 0: 0
be: 1: 256
le: 1: 256
be: 2: 512
le: 2: 512
be: 8388606: 2147483136
le: 8388606: 2147483136
be: 8388607: 2147483392
le: 8388607: 2147483392
C:\test>junk101 (version 3)
be: -8388608: 72057594029539328
le: -8388608: 72057594029539328
be: -8388607: 72057594029539329
le: -8388607: 72057594029539329
be: -2: 72057594037927934
le: -2: 72057594037927934
be: -1: 72057594037927935
le: -1: 72057594037927935
be: 0: 0
le: 0: 0
be: 1: 1
le: 1: 1
be: 2: 2
le: 2: 2
be: 8388606: 8388606
le: 8388606: 8388606
be: 8388607: 8388607
le: 8388607: 8388607
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |
Re^2: 3-byte representation
by BrowserUk (Patriarch) on Oct 12, 2011 at 19:12 UTC
|
Update: The >> 8 got dropped when I posted my solution. Fixed.
Silently becomes
Update: The /256 got dropped when I posted my solution. Fixed.
Hm. "Got dropped" huh!
| [reply] |
|
Thank you for all your gentle answers, but if I run this:
#!/usr/bin/perl
print "Content-type: text/html\n\n";
srand();
$fil="ch";
open(OUT, '>>'.$fil);
for($i=1;$i<10001;$i++){
$j=int(rand(20000))+440000;
$k=substr(pack('l>',$j),1);
print OUT $k;
}
close(OUT);
print "DONE !";
it produces one file with a variable length, but always greater than 30000 characters (for exemple 30045) !
So I suppose something is wrong in the pack line coding... | [reply] [d/l] |
|
| [reply] [d/l] [select] |
|
|
|
|
It was /256. Just misremembered cause I changed comps in the middle.
| [reply] |
|
| [reply] |
|
|
|