X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pod%2Fperlfaq4.pod;h=f602d24b27527049750f198887d0477435ce0d01;hb=8a36125691db1d8f79e98507373cbc6ea47271d4;hp=8624585f8631dda8bf8db1334c03758e25f312e8;hpb=cc30d1a74694698675ecf14ad1a395423bc5e13f;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pod/perlfaq4.pod b/pod/perlfaq4.pod index 8624585..f602d24 100644 --- a/pod/perlfaq4.pod +++ b/pod/perlfaq4.pod @@ -1,6 +1,6 @@ =head1 NAME -perlfaq4 - Data Manipulation ($Revision: 1.5 $, $Date: 2001/10/12 15:20:13 $) +perlfaq4 - Data Manipulation ($Revision: 1.8 $, $Date: 2001/11/09 08:06:04 $) =head1 DESCRIPTION @@ -123,24 +123,130 @@ Perl numbers whose absolute values are integers under 2**31 (on 32 bit machines) will work pretty much like mathematical integers. Other numbers are not guaranteed. -=head2 How do I convert bits into ints? +=head2 How do I convert between numeric representations: -To turn a string of 1s and 0s like C<10110110> into a scalar containing -its binary value, use the pack() and unpack() functions (documented in -L and L): +As always with Perl there is more than one way to do it. Below +are a few examples of approaches to making common conversions +between number representations. This is intended to be representational +rather than exhaustive. - $decimal = unpack('c', pack('B8', '10110110')); +Some of the examples below use the Bit::Vector module from CPAN. +The reason you might choose Bit::Vector over the perl built in +functions is that it works with numbers of ANY size, that it is +optimized for speed on some operations, and for at least some +programmers the notation might be familiar. -This packs the string C<10110110> into an eight bit binary structure. -This is then unpacked as a character, which returns its ordinal value. +=item B -This does the same thing: +Using perl's built in conversion of 0x notation: + + $int = 0xDEADBEEF; + $dec = sprintf("%d", $int); + +Using the hex function: + + $int = hex("DEADBEEF"); + $dec = sprintf("%d", $int); + +Using pack: + + $int = unpack("N", pack("H8", substr("0" x 8 . "DEADBEEF", -8))); + $dec = sprintf("%d", $int); + +Using the CPAN module Bit::Vector: + + use Bit::Vector; + $vec = Bit::Vector->new_Hex(32, "DEADBEEF"); + $dec = $vec->to_Dec(); + +=item B + +Using sprint: + + $hex = sprintf("%X", 3735928559); + +Using unpack + + $hex = unpack("H*", pack("N", 3735928559)); + +Using Bit::Vector + + use Bit::Vector; + $vec = Bit::Vector->new_Dec(32, -559038737); + $hex = $vec->to_Hex(); + +And Bit::Vector supports odd bit counts: + + use Bit::Vector; + $vec = Bit::Vector->new_Dec(33, 3735928559); + $vec->Resize(32); # suppress leading 0 if unwanted + $hex = $vec->to_Hex(); + +=item B + +Using Perl's built in conversion of numbers with leading zeros: + + $int = 033653337357; # note the leading 0! + $dec = sprintf("%d", $int); + +Using the oct function: + + $int = oct("33653337357"); + $dec = sprintf("%d", $int); + +Using Bit::Vector: + + use Bit::Vector; + $vec = Bit::Vector->new(32); + $vec->Chunk_List_Store(3, split(//, reverse "33653337357")); + $dec = $vec->to_Dec(); + +=item B + +Using sprintf: + + $oct = sprintf("%o", 3735928559); + +Using Bit::Vector + + use Bit::Vector; + $vec = Bit::Vector->new_Dec(32, -559038737); + $oct = reverse join('', $vec->Chunk_List_Read(3)); + +=item B + +Using pack and ord $decimal = ord(pack('B8', '10110110')); -Here's an example of going the other way: +Using pack and unpack for larger strings + + $int = unpack("N", pack("B32", + substr("0" x 32 . "11110101011011011111011101111", -32))); + $dec = sprintf("%d", $int); + + # substr() is used to left pad a 32 character string with zeros. + +Using Bit::Vector: + + $vec = Bit::Vector->new_Bin(32, "11011110101011011011111011101111"); + $dec = $vec->to_Dec(); + +=item B + +Using unpack; + + $bin = unpack("B*", pack("N", 3735928559)); + +Using Bit::Vector: + + use Bit::Vector; + $vec = Bit::Vector->new_Dec(32, -559038737); + $bin = $vec->to_Bin(); + +The remaining transformations (e.g. hex -> oct, bin -> hex, etc.) +are left as an exercise to the inclined reader. - $binary_string = unpack('B*', "\x29"); =head2 Why doesn't & work the way I want it to? @@ -216,7 +322,7 @@ will not create a list of 500,000 integers. =head2 How can I output Roman numerals? -Get the http://www.perl.com/CPAN/modules/by-module/Roman module. +Get the http://www.cpan.org/modules/by-module/Roman module. =head2 Why aren't my random numbers random? @@ -228,7 +334,7 @@ than more. Computers are good at being predictable and bad at being random (despite appearances caused by bugs in your programs :-). -http://www.perl.com/CPAN/doc/FMTEYEWTK/random , courtesy of Tom +http://www.cpan.org/doc/FMTEYEWTK/random , courtesy of Tom Phoenix, talks more about this. John von Neumann said, ``Anyone who attempts to generate random numbers by deterministic means is, of course, living in a state of sin.'' @@ -1367,7 +1473,7 @@ If you need to sort on several fields, the following paradigm is useful. This can be conveniently combined with precalculation of keys as given above. -See http://www.perl.com/CPAN/doc/FMTEYEWTK/sort.html for more about +See http://www.cpan.org/doc/FMTEYEWTK/sort.html for more about this approach. See also the question below on sorting hashes.