Skip to content

Commit 3746dea

Browse files
committed
Math::Complex: fix more parsing corner cases
In particular, '23i' now parses as 0 + 23i, not 2 + 3i. Also handle 'inf', '-inf', 'infi', and '-infi' correctly.
1 parent 8811686 commit 3746dea

File tree

2 files changed

+73
-11
lines changed

2 files changed

+73
-11
lines changed

dist/Math-Complex/lib/Math/Complex.pm

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ my %LOGN;
112112

113113
# Regular expression for floating point numbers.
114114
# These days we could use Scalar::Util::lln(), I guess.
115-
my $gre = qr'\s*([\+\-]?(?:(?:(?:\d+(?:_\d+)*(?:\.\d*(?:_\d+)*)?|\.\d+(?:_\d+)*)(?:[eE][\+\-]?\d+(?:_\d+)*)?))|inf)'i;
115+
my $gre = qr'\s*([\+\-]?(?:(?:(?:\d+(?:_\d+)*(?:\.\d*(?:_\d+)*)?|\.\d+(?:_\d+)*)(?:[eE][\+\-]?\d+(?:_\d+)*)?)|inf))'i;
116116

117117
require Exporter;
118118

@@ -196,25 +196,31 @@ sub _cannot_make {
196196
die "@{[(caller(1))[3]]}: Cannot take $_[0] of '$_[1]'.\n";
197197
}
198198

199+
sub _normalize_num {
200+
my $x = shift;
201+
$x =~ s/^\+//;
202+
$x =~ s/_//g;
203+
$x =~ s/^(-?)inf$/$1 ? -Inf() : Inf()/ie if $has_inf;
204+
return $x;
205+
}
206+
199207
sub _make {
200208
my $arg = shift;
201209
my ($p, $q);
202210

203211
if ($arg =~ /^$gre$/) {
204212
($p, $q) = ($1, 0);
205-
} elsif ($arg =~ /^(?:$gre)?$gre\s*i\s*$/) {
213+
} elsif ($arg =~ /^(?:$gre(?=\s*[+\-]))?$gre\s*i\s*$/) {
206214
($p, $q) = ($1 || 0, $2);
207-
} elsif ($arg =~ /^(?:$gre)?\s*([+\-]?)i\s*$/) {
215+
} elsif ($arg =~ /^(?:$gre(?=\s*[+\-]))?\s*([+\-]?)i\s*$/) {
208216
($p, $q) = ($1 || 0, $2 . '1');
209217
} elsif ($arg =~ /^\s*\($gre\s*(?:,$gre\s*)?\)\s*$/) {
210218
($p, $q) = ($1, $2 || 0);
211219
}
212220

213221
if (defined $p) {
214-
$p =~ s/^\+//;
215-
$p =~ s/^(-?)inf$/"${1}9**9**9"/e if $has_inf;
216-
$q =~ s/^\+//;
217-
$q =~ s/^(-?)inf$/"${1}9**9**9"/e if $has_inf;
222+
$p = _normalize_num $p;
223+
$q = _normalize_num $q;
218224
}
219225

220226
return ($p, $q);
@@ -235,10 +241,8 @@ sub _emake {
235241
}
236242

237243
if (defined $p) {
238-
$p =~ s/^\+//;
239-
$q =~ s/^\+//;
240-
$p =~ s/^(-?)inf$/"${1}9**9**9"/e if $has_inf;
241-
$q =~ s/^(-?)inf$/"${1}9**9**9"/e if $has_inf;
244+
$p = _normalize_num $p;
245+
$q = _normalize_num $q;
242246
}
243247

244248
return ($p, $q);

dist/Math-Complex/t/Complex.t

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,22 @@ EOS
347347
print "ok $test\n";
348348
EOS
349349

350+
$test++;
351+
push @script, <<EOS;
352+
print "# make 23i\n";
353+
\$z = Math::Complex->make('23i');
354+
print "not " unless \$z == cplx(0,23);
355+
print "ok $test\n";
356+
EOS
357+
358+
$test++;
359+
push @script, <<EOS;
360+
print "# make i\n";
361+
\$z = Math::Complex->make('i');
362+
print "not " unless \$z == cplx(0,1);
363+
print "ok $test\n";
364+
EOS
365+
350366
$test++;
351367
push @script, <<EOS;
352368
print "# remake 2+i\n";
@@ -363,6 +379,48 @@ EOS
363379
print "ok $test\n";
364380
EOS
365381

382+
if ($has_inf) {
383+
$test++;
384+
push @script, <<EOS;
385+
print "# make inf\n";
386+
\$z = Math::Complex->make('inf');
387+
print "not " unless \$z == cplx(\$inf, 0);
388+
print "ok $test\n";
389+
EOS
390+
391+
$test++;
392+
push @script, <<EOS;
393+
print "# make -inf\n";
394+
\$z = Math::Complex->make('-inf');
395+
print "not " unless \$z == cplx(-\$inf, 0);
396+
print "ok $test\n";
397+
EOS
398+
399+
$test++;
400+
push @script, <<EOS;
401+
print "# make infi\n";
402+
\$z = Math::Complex->make('infi');
403+
print "not " unless \$z == cplx(0, \$inf);
404+
print "ok $test\n";
405+
EOS
406+
407+
$test++;
408+
push @script, <<EOS;
409+
print "# make -infi\n";
410+
\$z = Math::Complex->make('-infi');
411+
print "not " unless \$z == cplx(0, -\$inf);
412+
print "ok $test\n";
413+
EOS
414+
415+
$test++;
416+
push @script, <<EOS;
417+
print "# make -infi\n";
418+
\$z = Math::Complex->make('inf+infi');
419+
print "not " unless \$z == cplx(\$inf, \$inf);
420+
print "ok $test\n";
421+
EOS
422+
}
423+
366424
$test++;
367425
push @script, <<EOS;
368426
print "# emake [2,3]\n";

0 commit comments

Comments
 (0)