view release on metacpan or search on metacpan
lib/nvec.pm view on Meta::CPAN
my $c = $v->where($mask);
Select elements where mask is non-zero.
=head1 SPECIAL VALUE CHECKS
=head2 isnan
my $c = $v->isnan();
Return 1.0 where element is NaN, 0.0 otherwise.
=head2 isinf
my $c = $v->isinf();
Return 1.0 where element is infinite, 0.0 otherwise.
=head2 isfinite
my $c = $v->isfinite();
t/1030-util-predicates-valid.t view on Meta::CPAN
subtest 'is_num edge cases' => sub {
# String that looks like number
ok(is_num('42'), 'is_num: string 42');
ok(is_num('3.14'), 'is_num: string 3.14');
ok(is_num('-5'), 'is_num: string -5');
ok(is_num('1e10'), 'is_num: string scientific');
# Special values (Perl's looks_like_number considers these numeric)
ok(is_num(0.0), 'is_num: 0.0');
ok(is_num('NaN'), 'is_num: string NaN (Perl considers numeric)');
ok(is_num('inf'), 'is_num: string inf (Perl considers numeric)');
# Whitespace (Perl's looks_like_number accepts leading/trailing spaces)
ok(is_num(' 42 '), 'is_num: number with spaces (Perl accepts)');
ok(!is_num('42abc'), 'is_num: number with trailing text');
};
# ============================================
# is_int
# ============================================
t/4012-object-neuralnet.t view on Meta::CPAN
for my $epoch (1 .. 500) {
for my $sample (@data) {
$net->train_step($sample->[0], $sample->[1]);
}
}
# Get final loss
my $final_loss = 0;
for my $sample (@data) {
my $pred = $net->predict($sample->[0]);
next unless defined $pred->[0] && $pred->[0] == $pred->[0]; # skip NaN
$final_loss += $net->loss_fn->mse->($pred, $sample->[1]);
}
# Just verify training ran without crashing and loss is finite
ok(defined $final_loss, 'training completed');
ok($final_loss == $final_loss, 'final loss is not NaN'); # NaN != NaN
# Test that predict returns valid output
my $out = $net->predict([1, 1]);
ok(ref($out) eq 'ARRAY', 'predict returns array');
ok(scalar(@$out) == 1, 'predict returns correct size');
ok(defined $out->[0], 'output is defined');
};
# ============================================
# Test function-style accessors work correctly
t/7007-vec-more-functions.t view on Meta::CPAN
# Test median
my $odd = nvec::new([3, 1, 2]);
is($odd->median, 2, 'median of [3,1,2] = 2');
my $even = nvec::new([4, 1, 3, 2]);
is($even->median, 2.5, 'median of [4,1,3,2] = 2.5');
# Test isnan/isinf/isfinite
use POSIX qw(HUGE_VAL);
my $nan = HUGE_VAL - HUGE_VAL; # NaN
my $inf = HUGE_VAL; # Inf
my $ninf = -(HUGE_VAL); # -Inf
my $special = nvec::new([1.0, $nan, $inf, $ninf]); # 1, NaN, Inf, -Inf
my $isnan = $special->isnan();
is($isnan->get(0), 0, 'isnan(1) = 0');
is($isnan->get(1), 1, 'isnan(NaN) = 1');
is($isnan->get(2), 0, 'isnan(Inf) = 0');
my $isinf = $special->isinf();
is($isinf->get(0), 0, 'isinf(1) = 0');
is($isinf->get(1), 0, 'isinf(NaN) = 0');
is($isinf->get(2), 1, 'isinf(Inf) = 1');
is($isinf->get(3), 1, 'isinf(-Inf) = 1');
my $isfinite = $special->isfinite();
is($isfinite->get(0), 1, 'isfinite(1) = 1');
is($isfinite->get(1), 0, 'isfinite(NaN) = 0');
is($isfinite->get(2), 0, 'isfinite(Inf) = 0');
done_testing();
t/7013-nvec-boolean-truth.t view on Meta::CPAN
is_deeply($ones->sign->to_array, [1, 1, 1], 'sign of ones');
};
# ============================================
# Special value checks
# ============================================
subtest 'isfinite, isnan, isinf' => sub {
use POSIX qw(HUGE_VAL);
my $inf = HUGE_VAL;
my $nan = $inf - $inf; # NaN
my $v = nvec::new([1.0, $nan, $inf, -$inf, 0]);
my $finite = $v->isfinite;
is($finite->get(0), 1, 'isfinite: 1.0');
is($finite->get(1), 0, 'isfinite: NaN');
is($finite->get(2), 0, 'isfinite: Inf');
is($finite->get(3), 0, 'isfinite: -Inf');
is($finite->get(4), 1, 'isfinite: 0');
my $is_nan = $v->isnan;
is($is_nan->get(0), 0, 'isnan: 1.0');
is($is_nan->get(1), 1, 'isnan: NaN');
is($is_nan->get(2), 0, 'isnan: Inf');
my $is_inf = $v->isinf;
is($is_inf->get(0), 0, 'isinf: 1.0');
is($is_inf->get(1), 0, 'isinf: NaN');
is($is_inf->get(2), 1, 'isinf: Inf');
is($is_inf->get(3), 1, 'isinf: -Inf');
};
# ============================================
# Chained boolean operations
# ============================================
subtest 'chained truth operations' => sub {
my $data = nvec::new([1, 0, 3, 0, 5, 0, 7, 0, 9, 0]);
t/7024-nvec-float-checks.t view on Meta::CPAN
use lib 'blib/lib', 'blib/arch', 't/lib';
use nvec;
use TestVec qw(is_quadmath);
if (is_quadmath()) {
diag("Testing with quadmath (128-bit precision)");
}
# Helper to get special values
my $nan = 9**9**9 - 9**9**9; # NaN
my $inf = 9**9**9; # Infinity
my $ninf = -9**9**9; # Negative infinity
subtest 'isnan - basic' => sub {
my $v = nvec::new([1, $nan, 3, $nan, 5]);
my $result = $v->isnan;
is($result->len, 5, 'isnan result has correct length');
my @vals = @{$result->to_array};
is($vals[0], 0, 'isnan: 1 is not NaN');
is($vals[1], 1, 'isnan: NaN is NaN');
is($vals[2], 0, 'isnan: 3 is not NaN');
is($vals[3], 1, 'isnan: NaN is NaN');
is($vals[4], 0, 'isnan: 5 is not NaN');
};
subtest 'isnan - no NaN values' => sub {
my $v = nvec::new([1, 2, 3, 4, 5]);
my $result = $v->isnan;
is($result->count, 0, 'no NaN values found');
};
subtest 'isnan - all NaN' => sub {
my $v = nvec::new([$nan, $nan, $nan]);
my $result = $v->isnan;
is($result->count, 3, 'all values are NaN');
};
subtest 'isnan - infinity is not NaN' => sub {
my $v = nvec::new([$inf, $ninf, 0]);
my $result = $v->isnan;
my @vals = @{$result->to_array};
is($vals[0], 0, 'isnan: +inf is not NaN');
is($vals[1], 0, 'isnan: -inf is not NaN');
is($vals[2], 0, 'isnan: 0 is not NaN');
};
subtest 'isinf - basic' => sub {
my $v = nvec::new([1, $inf, 3, $ninf, 5]);
my $result = $v->isinf;
is($result->len, 5, 'isinf result has correct length');
my @vals = @{$result->to_array};
is($vals[0], 0, 'isinf: 1 is not inf');
is($vals[1], 1, 'isinf: +inf is inf');
t/7024-nvec-float-checks.t view on Meta::CPAN
is($vals[4], 0, 'isinf: 5 is not inf');
};
subtest 'isinf - no infinite values' => sub {
my $v = nvec::new([1, 2, 3, 4, 5]);
my $result = $v->isinf;
is($result->count, 0, 'no infinite values found');
};
subtest 'isinf - NaN is not infinite' => sub {
my $v = nvec::new([$nan, 0, 1]);
my $result = $v->isinf;
my @vals = @{$result->to_array};
is($vals[0], 0, 'isinf: NaN is not infinite');
is($vals[1], 0, 'isinf: 0 is not infinite');
is($vals[2], 0, 'isinf: 1 is not infinite');
};
subtest 'isfinite - basic' => sub {
my $v = nvec::new([1, $inf, $nan, $ninf, 5]);
my $result = $v->isfinite;
is($result->len, 5, 'isfinite result has correct length');
my @vals = @{$result->to_array};
is($vals[0], 1, 'isfinite: 1 is finite');
is($vals[1], 0, 'isfinite: +inf is not finite');
is($vals[2], 0, 'isfinite: NaN is not finite');
is($vals[3], 0, 'isfinite: -inf is not finite');
is($vals[4], 1, 'isfinite: 5 is finite');
};
subtest 'isfinite - all finite' => sub {
my $v = nvec::new([1, 2, 3, 4, 5]);
my $result = $v->isfinite;
is($result->count, 5, 'all values are finite');
};
t/7024-nvec-float-checks.t view on Meta::CPAN
my $finite_mask = $v->isfinite;
my $finite_only = $v->where($finite_mask);
is($finite_only->len, 4, 'filtered to 4 finite values');
is_deeply($finite_only->to_array, [1, 3, 5, 7], 'correct finite values');
};
subtest 'combined: count special values' => sub {
my $v = nvec::new([1, $nan, $inf, 4, $ninf, $nan, 7]);
is($v->isnan->count, 2, '2 NaN values');
is($v->isinf->count, 2, '2 infinite values');
is($v->isfinite->count, 3, '3 finite values');
};
subtest 'operations producing special values' => sub {
my $a = nvec::new([0, 1, -1, 0]);
my $b = nvec::new([0, 0, 0, 1]);
my $result = $a->div($b); # 0/0=NaN, 1/0=inf, -1/0=-inf, 0/1=0
my @vals = @{$result->to_array};
ok($result->isnan->to_array->[0], '0/0 produces NaN');
ok($result->isinf->to_array->[1], '1/0 produces inf');
ok($result->isinf->to_array->[2], '-1/0 produces inf');
ok($result->isfinite->to_array->[3], '0/1 is finite');
};
done_testing();
t/7027-nvec-arithmetic-edge.t view on Meta::CPAN
subtest 'add: infinity handling' => sub {
my $v = nvec::new([1, 2, 3]);
my $c = $v->add_scalar($inf);
my @vals = @{$c->to_array};
ok($c->isinf->get(0), 'finite + inf = inf');
ok($c->isinf->get(1), 'finite + inf = inf');
ok($c->isinf->get(2), 'finite + inf = inf');
};
subtest 'add: inf + (-inf) = NaN' => sub {
my $a = nvec::new([$inf]);
my $b = nvec::new([$ninf]);
my $c = $a->add($b);
ok($c->isnan->get(0), 'inf + (-inf) = NaN');
};
# ============================================
# Subtraction edge cases
# ============================================
subtest 'sub: vector - vector' => sub {
my $a = nvec::new([5, 7, 9]);
my $b = nvec::new([1, 2, 3]);
t/7027-nvec-arithmetic-edge.t view on Meta::CPAN
is_deeply($c->to_array, [5, 15, 25], 'vector - scalar');
};
subtest 'sub: v - v = 0' => sub {
my $v = nvec::new([1.5, 2.5, 3.5]);
my $c = $v->sub($v);
my $zeros = nvec::zeros(3);
ok(vec_approx_eq($c, $zeros), 'v - v = 0');
};
subtest 'sub: inf - inf = NaN' => sub {
my $a = nvec::new([$inf]);
my $c = $a->sub($a);
ok($c->isnan->get(0), 'inf - inf = NaN');
};
# ============================================
# Multiplication edge cases
# ============================================
subtest 'mul: vector * vector' => sub {
my $a = nvec::new([2, 3, 4]);
my $b = nvec::new([5, 6, 7]);
t/7027-nvec-arithmetic-edge.t view on Meta::CPAN
};
subtest 'mul: with ones' => sub {
my $v = nvec::new([1, 2, 3]);
my $ones = nvec::ones(3);
my $c = $v->mul($ones);
ok(vec_approx_eq($c, $v), 'v * 1 = v');
};
subtest 'mul: 0 * inf = NaN' => sub {
my $a = nvec::new([0]);
my $b = nvec::new([$inf]);
my $c = $a->mul($b);
ok($c->isnan->get(0), '0 * inf = NaN');
};
subtest 'mul: negative * negative = positive' => sub {
my $a = nvec::new([-2, -3, -4]);
my $b = nvec::new([-5, -6, -7]);
my $c = $a->mul($b);
my @vals = @{$c->to_array};
ok($vals[0] > 0, 'negative * negative > 0');
ok($vals[1] > 0, 'negative * negative > 0');
t/7027-nvec-arithmetic-edge.t view on Meta::CPAN
ok(vec_approx_eq($c, $v), 'v / 1 = v');
};
subtest 'div: by zero produces infinity' => sub {
my $a = nvec::new([1, -1, 0]);
my $b = nvec::new([0, 0, 0]);
my $c = $a->div($b);
ok($c->isinf->get(0), '1/0 = inf');
ok($c->isinf->get(1), '-1/0 = -inf');
ok($c->isnan->get(2), '0/0 = NaN');
};
subtest 'div: inf / inf = NaN' => sub {
my $a = nvec::new([$inf]);
my $b = nvec::new([$inf]);
my $c = $a->div($b);
ok($c->isnan->get(0), 'inf / inf = NaN');
};
subtest 'div: finite / inf = 0' => sub {
my $a = nvec::new([1, 100, -50]);
my $b = nvec::new([$inf, $inf, $inf]);
my $c = $a->div($b);
my @vals = @{$c->to_array};
ok(approx_eq($vals[0], 0, $tol), 'finite / inf = 0');
ok(approx_eq($vals[1], 0, $tol), 'finite / inf = 0');
t/lib/TestVec.pm view on Meta::CPAN
$ulps //= 4;
return 1 if !defined $got && !defined $expected;
return 0 if !defined $got || !defined $expected;
# Handle exact zero
return $got == 0 if $expected == 0;
return $expected == 0 if $got == 0;
# Handle infinities
return $got == $expected if $got != $got || $expected != $expected; # NaN
# Relative comparison
my $max_abs = abs($got) > abs($expected) ? abs($got) : abs($expected);
my $diff = abs($got - $expected);
return $diff <= $NV_INFO{machine_epsilon} * $max_abs * $ulps;
}
# 3. ULP (Units in Last Place) comparison - most rigorous
# Counts how many representable floats apart two values are
sub ulp_distance {
my ($a, $b) = @_;
return 0 if !defined $a && !defined $b;
return -1 if !defined $a || !defined $b; # Error indicator
# Handle special cases
return 0 if $a == $b; # Exact match (handles infinities)
return -1 if $a != $a || $b != $b; # NaN
# For ULP calculation, we use the difference scaled by epsilon
# This is a portable approximation that works across NV types
my $max_abs = abs($a) > abs($b) ? abs($a) : abs($b);
$max_abs = 1.0 if $max_abs == 0; # Prevent division by zero
my $ulps = abs($a - $b) / ($NV_INFO{machine_epsilon} * $max_abs);
return int($ulps + 0.5); # Round to nearest integer
}
sub ulp_equal {
my ($got, $expected, $max_ulps) = @_;
$max_ulps //= 4;
my $dist = ulp_distance($got, $expected);
return 0 if $dist < 0; # Error case (NaN, undef)
return $dist <= $max_ulps;
}
# 4. Exact bit comparison - no tolerance
sub bits_equal {
my ($a, $b) = @_;
return 0 if !defined $a || !defined $b;
return pack("F", $a) eq pack("F", $b);
}
xs/const/ppport.h view on Meta::CPAN
s++; if (s == send || (*s != 'F' && *s != 'f')) return 0;
s++; if (s < send && (*s == 'I' || *s == 'i')) {
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++; if (s == send || (*s != 'I' && *s != 'i')) return 0;
s++; if (s == send || (*s != 'T' && *s != 't')) return 0;
s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0;
s++;
}
sawinf = 1;
} else if (*s == 'N' || *s == 'n') {
/* XXX TODO: There are signaling NaNs and quiet NaNs. */
s++; if (s == send || (*s != 'A' && *s != 'a')) return 0;
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++;
sawnan = 1;
} else
return 0;
if (sawinf) {
numtype &= IS_NUMBER_NEG; /* Keep track of sign */
numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT;
xs/doubly/ppport.h view on Meta::CPAN
s++; if (s == send || (*s != 'F' && *s != 'f')) return 0;
s++; if (s < send && (*s == 'I' || *s == 'i')) {
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++; if (s == send || (*s != 'I' && *s != 'i')) return 0;
s++; if (s == send || (*s != 'T' && *s != 't')) return 0;
s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0;
s++;
}
sawinf = 1;
} else if (*s == 'N' || *s == 'n') {
/* XXX TODO: There are signaling NaNs and quiet NaNs. */
s++; if (s == send || (*s != 'A' && *s != 'a')) return 0;
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++;
sawnan = 1;
} else
return 0;
if (sawinf) {
numtype &= IS_NUMBER_NEG; /* Keep track of sign */
numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT;
xs/file/ppport.h view on Meta::CPAN
s++; if (s == send || (*s != 'F' && *s != 'f')) return 0;
s++; if (s < send && (*s == 'I' || *s == 'i')) {
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++; if (s == send || (*s != 'I' && *s != 'i')) return 0;
s++; if (s == send || (*s != 'T' && *s != 't')) return 0;
s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0;
s++;
}
sawinf = 1;
} else if (*s == 'N' || *s == 'n') {
/* XXX TODO: There are signaling NaNs and quiet NaNs. */
s++; if (s == send || (*s != 'A' && *s != 'a')) return 0;
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++;
sawnan = 1;
} else
return 0;
if (sawinf) {
numtype &= IS_NUMBER_NEG; /* Keep track of sign */
numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT;
xs/heap/ppport.h view on Meta::CPAN
s++; if (s == send || (*s != 'F' && *s != 'f')) return 0;
s++; if (s < send && (*s == 'I' || *s == 'i')) {
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++; if (s == send || (*s != 'I' && *s != 'i')) return 0;
s++; if (s == send || (*s != 'T' && *s != 't')) return 0;
s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0;
s++;
}
sawinf = 1;
} else if (*s == 'N' || *s == 'n') {
/* XXX TODO: There are signaling NaNs and quiet NaNs. */
s++; if (s == send || (*s != 'A' && *s != 'a')) return 0;
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++;
sawnan = 1;
} else
return 0;
if (sawinf) {
numtype &= IS_NUMBER_NEG; /* Keep track of sign */
numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT;
xs/lru/ppport.h view on Meta::CPAN
s++; if (s == send || (*s != 'F' && *s != 'f')) return 0;
s++; if (s < send && (*s == 'I' || *s == 'i')) {
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++; if (s == send || (*s != 'I' && *s != 'i')) return 0;
s++; if (s == send || (*s != 'T' && *s != 't')) return 0;
s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0;
s++;
}
sawinf = 1;
} else if (*s == 'N' || *s == 'n') {
/* XXX TODO: There are signaling NaNs and quiet NaNs. */
s++; if (s == send || (*s != 'A' && *s != 'a')) return 0;
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++;
sawnan = 1;
} else
return 0;
if (sawinf) {
numtype &= IS_NUMBER_NEG; /* Keep track of sign */
numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT;
xs/noop/ppport.h view on Meta::CPAN
s++; if (s == send || (*s != 'F' && *s != 'f')) return 0;
s++; if (s < send && (*s == 'I' || *s == 'i')) {
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++; if (s == send || (*s != 'I' && *s != 'i')) return 0;
s++; if (s == send || (*s != 'T' && *s != 't')) return 0;
s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0;
s++;
}
sawinf = 1;
} else if (*s == 'N' || *s == 'n') {
/* XXX TODO: There are signaling NaNs and quiet NaNs. */
s++; if (s == send || (*s != 'A' && *s != 'a')) return 0;
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++;
sawnan = 1;
} else
return 0;
if (sawinf) {
numtype &= IS_NUMBER_NEG; /* Keep track of sign */
numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT;
xs/nvec/ppport.h view on Meta::CPAN
s++; if (s == send || (*s != 'F' && *s != 'f')) return 0;
s++; if (s < send && (*s == 'I' || *s == 'i')) {
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++; if (s == send || (*s != 'I' && *s != 'i')) return 0;
s++; if (s == send || (*s != 'T' && *s != 't')) return 0;
s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0;
s++;
}
sawinf = 1;
} else if (*s == 'N' || *s == 'n') {
/* XXX TODO: There are signaling NaNs and quiet NaNs. */
s++; if (s == send || (*s != 'A' && *s != 'a')) return 0;
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++;
sawnan = 1;
} else
return 0;
if (sawinf) {
numtype &= IS_NUMBER_NEG; /* Keep track of sign */
numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT;
xs/object/ppport.h view on Meta::CPAN
s++; if (s == send || (*s != 'F' && *s != 'f')) return 0;
s++; if (s < send && (*s == 'I' || *s == 'i')) {
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++; if (s == send || (*s != 'I' && *s != 'i')) return 0;
s++; if (s == send || (*s != 'T' && *s != 't')) return 0;
s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0;
s++;
}
sawinf = 1;
} else if (*s == 'N' || *s == 'n') {
/* XXX TODO: There are signaling NaNs and quiet NaNs. */
s++; if (s == send || (*s != 'A' && *s != 'a')) return 0;
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++;
sawnan = 1;
} else
return 0;
if (sawinf) {
numtype &= IS_NUMBER_NEG; /* Keep track of sign */
numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT;
xs/ppport.h view on Meta::CPAN
s++; if (s == send || (*s != 'F' && *s != 'f')) return 0;
s++; if (s < send && (*s == 'I' || *s == 'i')) {
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++; if (s == send || (*s != 'I' && *s != 'i')) return 0;
s++; if (s == send || (*s != 'T' && *s != 't')) return 0;
s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0;
s++;
}
sawinf = 1;
} else if (*s == 'N' || *s == 'n') {
/* XXX TODO: There are signaling NaNs and quiet NaNs. */
s++; if (s == send || (*s != 'A' && *s != 'a')) return 0;
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++;
sawnan = 1;
} else
return 0;
if (sawinf) {
numtype &= IS_NUMBER_NEG; /* Keep track of sign */
numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT;
xs/slot/ppport.h view on Meta::CPAN
s++; if (s == send || (*s != 'F' && *s != 'f')) return 0;
s++; if (s < send && (*s == 'I' || *s == 'i')) {
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++; if (s == send || (*s != 'I' && *s != 'i')) return 0;
s++; if (s == send || (*s != 'T' && *s != 't')) return 0;
s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0;
s++;
}
sawinf = 1;
} else if (*s == 'N' || *s == 'n') {
/* XXX TODO: There are signaling NaNs and quiet NaNs. */
s++; if (s == send || (*s != 'A' && *s != 'a')) return 0;
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++;
sawnan = 1;
} else
return 0;
if (sawinf) {
numtype &= IS_NUMBER_NEG; /* Keep track of sign */
numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT;
xs/util/ppport.h view on Meta::CPAN
s++; if (s == send || (*s != 'F' && *s != 'f')) return 0;
s++; if (s < send && (*s == 'I' || *s == 'i')) {
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++; if (s == send || (*s != 'I' && *s != 'i')) return 0;
s++; if (s == send || (*s != 'T' && *s != 't')) return 0;
s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0;
s++;
}
sawinf = 1;
} else if (*s == 'N' || *s == 'n') {
/* XXX TODO: There are signaling NaNs and quiet NaNs. */
s++; if (s == send || (*s != 'A' && *s != 'a')) return 0;
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++;
sawnan = 1;
} else
return 0;
if (sawinf) {
numtype &= IS_NUMBER_NEG; /* Keep track of sign */
numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT;