📄 perlfaq4.1
字号:
.SpUsing \f(CW\*(C`Bit::Vector\*(C'\fR:.Sp.Vb 4\& use Bit::Vector;\& $vec = Bit::Vector\->new(32);\& $vec\->Chunk_List_Store(3, split(//, reverse "33653337357"));\& $dec = $vec\->to_Dec();.Ve.IP "How do I convert from decimal to octal" 4.IX Item "How do I convert from decimal to octal"Using \f(CW\*(C`sprintf\*(C'\fR:.Sp.Vb 1\& $oct = sprintf("%o", 3735928559);.Ve.SpUsing \f(CW\*(C`Bit::Vector\*(C'\fR:.Sp.Vb 3\& use Bit::Vector;\& $vec = Bit::Vector\->new_Dec(32, \-559038737);\& $oct = reverse join(\*(Aq\*(Aq, $vec\->Chunk_List_Read(3));.Ve.IP "How do I convert from binary to decimal" 4.IX Item "How do I convert from binary to decimal"Perl 5.6 lets you write binary numbers directly withthe \f(CW\*(C`0b\*(C'\fR notation:.Sp.Vb 1\& $number = 0b10110110;.Ve.SpUsing \f(CW\*(C`oct\*(C'\fR:.Sp.Vb 2\& my $input = "10110110";\& $decimal = oct( "0b$input" );.Ve.SpUsing \f(CW\*(C`pack\*(C'\fR and \f(CW\*(C`ord\*(C'\fR:.Sp.Vb 1\& $decimal = ord(pack(\*(AqB8\*(Aq, \*(Aq10110110\*(Aq));.Ve.SpUsing \f(CW\*(C`pack\*(C'\fR and \f(CW\*(C`unpack\*(C'\fR for larger strings:.Sp.Vb 3\& $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..Ve.SpUsing \f(CW\*(C`Bit::Vector\*(C'\fR:.Sp.Vb 2\& $vec = Bit::Vector\->new_Bin(32, "11011110101011011011111011101111");\& $dec = $vec\->to_Dec();.Ve.IP "How do I convert from decimal to binary" 4.IX Item "How do I convert from decimal to binary"Using \f(CW\*(C`sprintf\*(C'\fR (perl 5.6+):.Sp.Vb 1\& $bin = sprintf("%b", 3735928559);.Ve.SpUsing \f(CW\*(C`unpack\*(C'\fR:.Sp.Vb 1\& $bin = unpack("B*", pack("N", 3735928559));.Ve.SpUsing \f(CW\*(C`Bit::Vector\*(C'\fR:.Sp.Vb 3\& use Bit::Vector;\& $vec = Bit::Vector\->new_Dec(32, \-559038737);\& $bin = $vec\->to_Bin();.Ve.SpThe remaining transformations (e.g. hex \-> oct, bin \-> hex, etc.)are left as an exercise to the inclined reader..Sh "Why doesn't & work the way I want it to?".IX Subsection "Why doesn't & work the way I want it to?"The behavior of binary arithmetic operators depends on whether they'reused on numbers or strings. The operators treat a string as a seriesof bits and work with that (the string \f(CW"3"\fR is the bit pattern\&\f(CW00110011\fR). The operators work with the binary form of a number(the number \f(CW3\fR is treated as the bit pattern \f(CW00000011\fR)..PPSo, saying \f(CW\*(C`11 & 3\*(C'\fR performs the \*(L"and\*(R" operation on numbers (yielding\&\f(CW3\fR). Saying \f(CW"11" & "3"\fR performs the \*(L"and\*(R" operation on strings(yielding \f(CW"1"\fR)..PPMost problems with \f(CW\*(C`&\*(C'\fR and \f(CW\*(C`|\*(C'\fR arise because the programmer thinksthey have a number but really it's a string. The rest arise becausethe programmer says:.PP.Vb 3\& if ("\e020\e020" & "\e101\e101") {\& # ...\& }.Ve.PPbut a string consisting of two null bytes (the result of \f(CW"\e020\e020"& "\e101\e101"\fR) is not a false value in Perl. You need:.PP.Vb 3\& if ( ("\e020\e020" & "\e101\e101") !~ /[^\e000]/) {\& # ...\& }.Ve.Sh "How do I multiply matrices?".IX Subsection "How do I multiply matrices?"Use the Math::Matrix or Math::MatrixReal modules (available from \s-1CPAN\s0)or the \s-1PDL\s0 extension (also available from \s-1CPAN\s0)..Sh "How do I perform an operation on a series of integers?".IX Subsection "How do I perform an operation on a series of integers?"To call a function on each element in an array, and collect theresults, use:.PP.Vb 1\& @results = map { my_func($_) } @array;.Ve.PPFor example:.PP.Vb 1\& @triple = map { 3 * $_ } @single;.Ve.PPTo call a function on each element of an array, but ignore theresults:.PP.Vb 3\& foreach $iterator (@array) {\& some_func($iterator);\& }.Ve.PPTo call a function on each integer in a (small) range, you \fBcan\fR use:.PP.Vb 1\& @results = map { some_func($_) } (5 .. 25);.Ve.PPbut you should be aware that the \f(CW\*(C`..\*(C'\fR operator creates an array ofall integers in the range. This can take a lot of memory for largeranges. Instead use:.PP.Vb 4\& @results = ();\& for ($i=5; $i < 500_005; $i++) {\& push(@results, some_func($i));\& }.Ve.PPThis situation has been fixed in Perl5.005. Use of \f(CW\*(C`..\*(C'\fR in a \f(CW\*(C`for\*(C'\fRloop will iterate over the range, without creating the entire range..PP.Vb 3\& for my $i (5 .. 500_005) {\& push(@results, some_func($i));\& }.Ve.PPwill not create a list of 500,000 integers..Sh "How can I output Roman numerals?".IX Subsection "How can I output Roman numerals?"Get the http://www.cpan.org/modules/by\-module/Roman module..Sh "Why aren't my random numbers random?".IX Subsection "Why aren't my random numbers random?"If you're using a version of Perl before 5.004, you must call \f(CW\*(C`srand\*(C'\fRonce at the start of your program to seed the random number generator..PP.Vb 1\& BEGIN { srand() if $] < 5.004 }.Ve.PP5.004 and later automatically call \f(CW\*(C`srand\*(C'\fR at the beginning. Don'tcall \f(CW\*(C`srand\*(C'\fR more than once\*(--you make your numbers less random,rather than more..PPComputers are good at being predictable and bad at being random(despite appearances caused by bugs in your programs :\-). see the\&\fIrandom\fR article in the \*(L"Far More Than You Ever Wanted To Know\*(R"collection in http://www.cpan.org/misc/olddoc/FMTEYEWTK.tgz , courtesyof Tom Phoenix, talks more about this. John von Neumann said, \*(L"Anyonewho attempts to generate random numbers by deterministic means is, ofcourse, living in a state of sin.\*(R".PPIf you want numbers that are more random than \f(CW\*(C`rand\*(C'\fR with \f(CW\*(C`srand\*(C'\fRprovides, you should also check out the \f(CW\*(C`Math::TrulyRandom\*(C'\fR module from\&\s-1CPAN\s0. It uses the imperfections in your system's timer to generaterandom numbers, but this takes quite a while. If you want a betterpseudorandom generator than comes with your operating system, look at\&\*(L"Numerical Recipes in C\*(R" at http://www.nr.com/ ..Sh "How do I get a random number between X and Y?".IX Subsection "How do I get a random number between X and Y?"To get a random number between two values, you can use the \f(CW\*(C`rand()\*(C'\fRbuiltin to get a random number between 0 and 1. From there, you shiftthat into the range that you want..PP\&\f(CW\*(C`rand($x)\*(C'\fR returns a number such that \f(CW\*(C`0 <= rand($x) < $x\*(C'\fR. Thuswhat you want to have perl figure out is a random number in the rangefrom 0 to the difference between your \fIX\fR and \fIY\fR..PPThat is, to get a number between 10 and 15, inclusive, you want arandom number between 0 and 5 that you can then add to 10..PP.Vb 1\& my $number = 10 + int rand( 15\-10+1 );.Ve.PPHence you derive the following simple function to abstractthat. It selects a random integer between the two givenintegers (inclusive), For example: \f(CW\*(C`random_int_between(50,120)\*(C'\fR..PP.Vb 7\& sub random_int_between {\& my($min, $max) = @_;\& # Assumes that the two arguments are integers themselves!\& return $min if $min == $max;\& ($min, $max) = ($max, $min) if $min > $max;\& return $min + int rand(1 + $max \- $min);\& }.Ve.SH "Data: Dates".IX Header "Data: Dates".Sh "How do I find the day or week of the year?".IX Subsection "How do I find the day or week of the year?"The localtime function returns the day of the year. Without anargument localtime uses the current time..PP.Vb 1\& $day_of_year = (localtime)[7];.Ve.PPThe \f(CW\*(C`POSIX\*(C'\fR module can also format a date as the day of the year orweek of the year..PP.Vb 3\& use POSIX qw/strftime/;\& my $day_of_year = strftime "%j", localtime;\& my $week_of_year = strftime "%W", localtime;.Ve.PPTo get the day of year for any date, use \f(CW\*(C`POSIX\*(C'\fR's \f(CW\*(C`mktime\*(C'\fR to geta time in epoch seconds for the argument to localtime..PP.Vb 3\& use POSIX qw/mktime strftime/;\& my $week_of_year = strftime "%W",\& localtime( mktime( 0, 0, 0, 18, 11, 87 ) );.Ve.PPThe \f(CW\*(C`Date::Calc\*(C'\fR module provides two functions to calculate these..PP.Vb 3\& use Date::Calc;\& my $day_of_year = Day_of_Year( 1987, 12, 18 );\& my $week_of_year = Week_of_Year( 1987, 12, 18 );.Ve.Sh "How do I find the current century or millennium?".IX Subsection "How do I find the current century or millennium?"Use the following simple functions:.PP.Vb 3\& sub get_century {\& return int((((localtime(shift || time))[5] + 1999))/100);\& }\&\& sub get_millennium {\& return 1+int((((localtime(shift || time))[5] + 1899))/1000);\& }.Ve.PPOn some systems, the \f(CW\*(C`POSIX\*(C'\fR module's \f(CW\*(C`strftime()\*(C'\fR function has beenextended in a non-standard way to use a \f(CW%C\fR format, which theysometimes claim is the \*(L"century\*(R". It isn't, because on most suchsystems, this is only the first two digits of the four-digit year, andthus cannot be used to reliably determine the current century ormillennium..Sh "How can I compare two dates and find the difference?".IX Subsection "How can I compare two dates and find the difference?"(contributed by brian d foy).PPYou could just store all your dates as a number and then subtract.Life isn't always that simple though. If you want to work withformatted dates, the \f(CW\*(C`Date::Manip\*(C'\fR, \f(CW\*(C`Date::Calc\*(C'\fR, or \f(CW\*(C`DateTime\*(C'\fRmodules can help you..Sh "How can I take a string and turn it into epoch seconds?".IX Subsection "How can I take a string and turn it into epoch seconds?"If it's a regular enough string that it always has the same format,you can split it up and pass the parts to \f(CW\*(C`timelocal\*(C'\fR in the standard\&\f(CW\*(C`Time::Local\*(C'\fR module. Otherwise, you should look into the \f(CW\*(C`Date::Calc\*(C'\fRand \f(CW\*(C`Date::Manip\*(C'\fR modules from \s-1CPAN\s0..Sh "How can I find the Julian Day?".IX Subsection "How can I find the Julian Day?"(contributed by brian d foy and Dave Cross).PPYou can use the \f(CW\*(C`Time::JulianDay\*(C'\fR module available on \s-1CPAN\s0. Ensurethat you really want to find a Julian day, though, as many people havedifferent ideas about Julian days. Seehttp://www.hermetic.ch/cal_stud/jdn.htm for instance..PPYou can also try the \f(CW\*(C`DateTime\*(C'\fR module, which can convert a date/timeto a Julian Day..PP.Vb 2\& $ perl \-MDateTime \-le\*(Aqprint DateTime\->today\->jd\*(Aq\& 2453401.5.Ve.PPOr the modified Julian Day.PP.Vb 2\& $ perl \-MDateTime \-le\*(Aqprint DateTime\->today\->mjd\*(Aq\& 53401.Ve.PPOr even the day of the year (which is what some people think of as aJulian day).PP.Vb 2\& $ perl \-MDateTime \-le\*(Aqprint DateTime\->today\->doy\*(Aq\& 31.Ve.Sh "How do I find yesterday's date?".IX Subsection "How do I find yesterday's date?"(contributed by brian d foy).PPUse one of the Date modules. The \f(CW\*(C`DateTime\*(C'\fR module makes it simple, andgive you the same time of day, only the day before..PP.Vb 1\& use DateTime;\&\& my $yesterday = DateTime\->now\->subtract( days => 1 );\&\& print "Yesterday was $yesterday\en";.Ve.PPYou can also use the \f(CW\*(C`Date::Calc\*(C'\fR module using its \f(CW\*(C`Today_and_Now\*(C'\fRfunction..PP.Vb 1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -