Okay, I think I have signed quads working...
#!/usr/bin/perl -w
use strict;
my $little;
BEGIN { $little= unpack "C", pack "S", 1; }
sub quad {
my( $str )= @_;
my $big;
if( ! eval { $big= unpack( "Q", $str ); 1; } ) {
my( $lo, $hi )= unpack "LL", $str;
( $hi, $lo )= ( $lo, $hi ) if ! $little;
$big= $lo + $hi*( 1 + ~0 );
if( $big+1 == $big ) {
warn "Forced to approximate!\n";
}
}
return $big;
}
sub squad {
my( $str )= @_;
my $big;
if( ! eval { $big= unpack( "Q", $str ); 1; } ) {
my( $lo, $hi )= unpack $little ? "Ll" : "lL", $str;
( $hi, $lo )= ( $lo, $hi ) if ! $little;
if( $hi < 0 ) {
$hi= ~$hi;
$lo= ~$lo;
$big= -1 -$lo - $hi*( 1 + ~0 );
} else {
$big= $lo + $hi*( 1 + ~0 );
}
if( $big+1 == $big ) {
warn "Forced to approximate!\n";
}
}
return $big;
}
my @quads= (
"\xff\xff\xff\xff\xff\xff\xff\xff",
"\x00\x3f\xed\xcb\xa9\x87\x65\x43",
"\x00\x1f\xff\xff\xff\xff\xff\xff" );
if( $little ) {
for( @quads ) {
$_= reverse $_;
}
}
$|= 1;
push @quads, ~$quads[1], ~$quads[2];
for( @quads ) {
print quad( $_ ), "\n";
print squad( $_ ), "\n\n";
}
if( quad($quads[2]) == -1 - squad($quads[4]) ) {
print "two's complement works!\n";
}
__END__
This prints:
Forced to approximate!
1.84467440737096e+019
-1
Forced to approximate!
1.79943825111381e+016
Forced to approximate!
1.79943825111381e+016
9.00719925474099e+015
9.00719925474099e+015
Forced to approximate!
1.84287496911984e+019
Forced to approximate!
-1.79943825111381e+016
Forced to approximate!
1.84377368744548e+019
-9.00719925474099e+015
two's complement works!
Though, squad() seems overly convoluted. Improvements welcome.
-
tye
(but my friends call me "Tye") |