ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП |
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы. |
2.4. Преобразования между двоичной и десятичной системами счисленияПроблемаИмеется десятичное число, которое необходимо вывести в двоичном представлении, или наоборот, двоичная последовательность, которую требуется преобразовать в десятичное число. Такие задачи часто возникают при отображении не-текстовых данных - например, полученных в процессе взаимодействия с некоторыми системными функциями и программами.РешениеЧтобы преобразовать целое число Perl в строку, состоящую из единиц и нулей, сначала упакуйте его в сетевой формат "N" (с начальным старшим байтом), а затем снова распакуйте по одному биту (формат "В32").sub dec2bin { my $str = unpack("B32", pack("N", shift)); $str =~ s/"0+C7=\d)//; # В противном случае появятся начальные нули return $str; } Чтобы преобразовать строку из единиц и нулей в целое число Perl, допилнип;
ее необходимым количеством нулей, а затем выполните описанную выше процедуру
в обратном порядке:
КомментарийРечь идет о преобразовании чисел между строками вида "00100011" и десятичной системой счисления (35). Строка содержит двоичное представление числа. На этот раз функция sprintfue поможет: в ней не предусмотрен формат для вывода чисел в двоичной системе счисления. Следовательно, нам придется прибегнуть к функциям Perl pack и unpack для непосредственных манипуляций со строковыми данными. Функции pack и unpack предназначены для работы со строками. Строки можно интерпретировать как последовательности битов, байты, целые, длинные целые, числа с плавающей запятой в представлении IEEE, контрольные суммы - не говоря уже о многом другом. Обе функции, pack и unpack, по аналогии со spnntf получают форматную строку, которая определяет выполняемые с аргументом операции. Мы используем pack и unpack для интерпретации строк как последовательностей битов и двоичного представления целого числа. Чтобы понять, каким образом строка интерпретируется как последовательность битов, необходимо хорошо разобраться в поведении функции pack. Строка интерпретируется как последо вательность байтов, состоящих из восьми бит. Байты всегда нумеруются слев:1 направо (первые восемь бит образуют первый байт, следующие восемь бит - второй и т. д.), однако внутри каждого байта биты могут нумероваться как слева направо, так и справа налево. Функция pack с шаблоном "В" работает с битами каждого байта, пронумеро ванными слева направо. Именно в этом порядке они должны находиться для при менения формата "N", которым мы воспользуемся для интерпретации последовательности битов как 32-разрядного целого.$num = bin2dec('0110110') # $num = 54 $binstr = dec2bin(54); # $binstr = 110110 2.5. Действия с последовательностями целых чиселПроблемаТребуется выполнить некоторую операцию со всеми целыми между Х и Y. Подобная задача возникает при работе с непрерывной частью массива или в любой ситуации, когда необходимо обработать все числа' из заданного интервала.РешениеВоспользуйтесь циклом for или . . в сочетании с циклом to reach:foreach ($X .. $Y) { # $_ принимает все целые значения от Х до Y включительно } foreach $i ($X .. $Y) { # $i принимает все целые значения от Х до Y включительно } foreach ($i = $X: $i <= $Y; $i++) { # $i принимает все целые значения от X до Y включительно } foreach ($1 = $Х; $i <= $Y; $i+=7) { # $i принимает целые значения от Х до Y включительно с шагом 7 } КомментарийВ первых двух методах используется конструкция $Х. . $Y, которая создает список всех целых чисел между $Х и $Y. Если $Х и $Y расположены далеко друг от друга, это приводит к большим расходам памяти (исправлено в версии 5.005). При организации перебора последовательных целых чисел цикл for из третьего способа расходует память более эффективно. В следующем фрагменте продемонстрированы все три способа. В данном случае мы ограничиваемся выводом сгенерированных чисел:print "Infancy is:"; foreach (0 .. 2) { print "$_ "; } print "\n"; print "Toddling is: "; foreach $i (3 .. 4) { Точнее, все целые числа. Найти все вещественные числа будет нелегко. Не верите - посмотрите у Кантора. print "$i ";
[> Смотри также -------------------------------
2.6. Работа с числами в римской записиПроблемаТребуется осуществить преобразование между обычными числами и числами в римской записи. Такая необходимость часто возникает при оформлении сносок и нумерации страниц в предисловиях.РешениеВоспользуйтесь модулем Roman с CPAN:use Roman; $roman = roman($arabic); # Преобразование # в римскую запись $arabic = arabic($roman) if isroman($roman); # Преобразование # из римской записи КомментарийДля преобразования арабских ("обычных") чисел в римские эквиваленты в модуле Roman предусмотрены две функции, Roman и roman. Первая выводит символы в верхнем регистре, а вторая - в нижнем. Модуль работает только с римскими числами от 1 до 3999 включительно. В римской записи пет отрицательных чисел или нуля, а для числа 5000 (с помощью которого представляется 4000) используется символ, не входящий в кодировку ASCII.use Roman;
> Смотри также -------------------------------
2.7. Генератор случайных чиселПроблемаТребуется генерировать случайные числа в заданном интервале - например, чтобы выбрать произвольный элемент массива, имитировать бросок кубика в игре или сгенерировать случайный пароль.РешениеВоспользуйтесь функцией Perl rand. $random = int( rand( $Y-$X+1 ) ) + $X; o Комментарий Следующий фрагмент генерирует и выводит случайное число в интервале от 25 до 75 включительно:$random = int( rand(51)) + 25;
$elt = $array[ rand @array ]; Также она часто используется для генерации случайного пароля из заданной последовательности символов: @chars = ( "А" .. "Z", "а" .. "z", 0 . . 9, qw(% ! 0 $%"&*)): $password = join("", @chars[ map { rand Ochars } ( 1 .. 8 ) ]); Мы генерируем восемь случайных индексов @chars с помощью функции тар, извлекаем соответствующие символы в виде среза и объединяем их в случайный пароль. Впрочем, в действительности пароль получается не совсем случайным - безопасность вашей системы зависит от стартового значения (seed) генератора случайных чисел на момент запуска программы. В рецепте 2.8 показано, как "раскрутить" генератор случайных чисел и сделать генерируемые числа более случайными. > Смотри также
2.8. Раскрутка генератора случайных чиселПроблемаПри каждом запуске программы вы получаете один и тот же набор "случайных" чисел. Требуется "раскрутить" генератор, чтобы Perl каждый раз генерировал разные числа. Это важно практически для любых применений случайных чисел, особенно для игр.РешениеВоспользуйтесь функцией Perl srand:srand EXPR; КомментарийГенерация случайных чисел - непростое дело. Лучшее, на что способен компьютер без специального оборудования, - генерация псевдослучайных чисел, равномерно распределенных в области своих значений. Псевдослучайные числа генерируются по математическим формулам, а это означает, что при одинаковом стартовом значении генератора две программы сгенерируют одни и те же псевдослучайные числа. Функция srand задает новое стартовое значение для генератора псевдослучайных чисел. Если она вызывается с аргументом, то указанное число будет использовано в качестве стартового. При отсутствии аргумента srand использует величину, значение которой трудно предсказать заранее (относится к Perl 5.004 и более поздним версиям; до этого использовалась функция time, значения которой совсем не были случайными). Не вызывайте srand в программе более одного раза. Если вы не вызвали srand сами, Perl версий 5.004 и выше вызывает srand с "хорошим" стартовым значением при первом запуске rand. Предыдущие версии этого не делали, поэтому программы всегда генерировали одну и ту же последовательность чисел. Если вы предпочитаете именно такое поведение, вызывайте srand с конкретным аргументом:srand( То, что Perl старается выбрать хорошее стартовое значение, еще не гарантирует криптографической безопасности сгенерированных чисел от усердных попыток взлома. Информацию о построении надежных генераторов случайных чисел можно найти в учебниках по криптографии. > Смотри также --------------------------------
|