PERL: БИБЛИОТЕКА ПРОГРАММИСТА


PERL: БИБЛИОТЕКА ПРОГРАММИСТА - стр. 77


unless /¦([+-]?)(?=\d|\.\d)\d*(V\d*)?([Ee]([+-p\d+))?$/;

В этих шаблонах не обрабатываются особые случаи Infinity и NaN в записи IEEE. Если вы не боитесь, что члены комитета IEEE придут к вашему компьюте­ру и начнут бить вас по голове копиями соответствующих стандартов, вероятно, об этих странных «числах» можно забыть.

Для строк с начальными или конечными пробелами эти шаблоны не подходят. Либо вставьте в них соответствующую логику, либо вызовите функцию trim из рецепта 1.14.

В POSIX-системах Perl поддерживает функцию POSIX: :strtod. Ее семанти­ка чрезвычайно громоздка, поэтому мы приведем функцию getnum для упроще­ния доступа. Эта функция получает строку и возвращает либо преобразованное число, либо undef для строк, не соответствующих вещественным числам С. Интер­фейсная функция is_numeric упрощает вызов getnum в ситуациях, когда вы просто хотите спросить: «Это вещественное число»?

sub getnum {

use POSIX qw(strtod);


70   Глава 2 • Числа

my $str = shift,

$str =~ s/\s+$//,

$i=0

my($num, Sunparsed) = strtod($str),

if (($str eq ") || (Sunparsed '=0) || $') {

return, } else {

return $num,

}

sub is_numeric { defined scalar &getnum }

> Смотри также------------------------------------------------------------------------

Описание синтаксиса регулярных выражений в perlre(i); страница руковод­ства strtod(3); документация по стандартному модулю POSIX.

2.2. Сравнение чисел с плавающей запятой

Проблема

Арифметика с плавающей запятой не является абсолютно точной. Сравнивая два числа, вы хотите узнать, совпадают ли они до определенного десятичного разряда. Как правило, именно так следует сравнивать числа с плавающей за­пятой.

Решение

Воспользуйтесь функцией sprintf и отформатируйте числа до определенного де­сятичного разряда, после чего сравните полученные строки:

# equal(NUM1, NUM2, ACCURACY), возвращает true если NUM1 и NUM2

#  совпадают на ACCURACY десятичных разрядов

sub equal {

my ($A $B, $dp) = @_,

return sprintf( % ${dp}g , $A) eq sprintf( % ${dp}g , $A), }




Начало  Назад  Вперед