package String::Numeric;
use strict;
use warnings;
BEGIN {
our $VERSION = 0.9;
our @EXPORT_OK = qw(
is_numeric
is_float
is_decimal
is_integer
is_int
is_int8
is_int16
is_int32
is_int64
is_int128
is_uint
is_uint8
is_uint16
is_uint32
is_uint64
is_uint128
);
our %EXPORT_TAGS = (
all => [ @EXPORT_OK ],
int => [ grep { /^is_int/ } @EXPORT_OK ],
uint => [ grep { /^is_uint/ } @EXPORT_OK ],
);
if ( !$ENV{STRING_NUMERIC_PP} ) {
eval {
require String::Numeric::XS;
};
}
if ( $ENV{STRING_NUMERIC_PP} || $@ ) {
require String::Numeric::PP;
String::Numeric::PP->import(@EXPORT_OK);
}
else {
String::Numeric::XS->import(@EXPORT_OK);
}
require Exporter;
*import = \&Exporter::import;
}
1;
__END__
=head1 NAME
String::Numeric - Determine whether a string represents a numeric value
=head1 SYNOPSIS
$boolean = is_float($string);
$boolean = is_decimal($string);
$boolean = is_int($string);
$boolean = is_int8($string);
$boolean = is_int16($string);
$boolean = is_int32($string);
$boolean = is_int64($string);
$boolean = is_int128($string);
$boolean = is_uint($string);
$boolean = is_uint8($string);
$boolean = is_uint16($string);
$boolean = is_uint32($string);
$boolean = is_uint64($string);
$boolean = is_uint128($string);
=head1 DESCRIPTION
A numeric value contains an integer part that may be prefixed with an
optional minus sign, which may be followed by a fractional part and/or an
exponent part.
See L</String::Numeric ABNF> for specification and L</COMPARISON> for a comparison with C<Scalar::Util::looks_like_number()>.
=head1 FUNCTIONS
=head2 is_float
Determine whether C<$string> is a floating-point number of arbitrary precision.
I<Usage>
$boolean = is_float($string);
$boolean = is_float('-1'); # true
$boolean = is_float('1'); # true
$boolean = is_float('1.0'); # true
$boolean = is_float('1.0e6'); # true
$boolean = is_float('1e6'); # true
$boolean = is_float(undef); # false
I<Arguments>
=over 4
=item C<$string>
=back
I<Returns>
=over 4
=item C<$boolean>
=back
I<Note>
=over 4
=item This function is also available as C<is_numeric()>
=back
=head2 is_decimal
Determine whether C<$string> is a decimal number of arbitrary precision.
I<Usage>
$boolean = is_decimal($string);
$boolean = is_decimal('-1'); # true
$boolean = is_decimal('1'); # true
$boolean = is_decimal('1.0'); # true
$boolean = is_decimal('1.0e6'); # false
$boolean = is_decimal('1e6'); # false
$boolean = is_decimal(undef); # false
I<Arguments>
=over 4
=item C<$string>
=back
I<Returns>
=over 4
=item C<$boolean>
=back
=head2 is_int
Determine whether C<$string> is an integer of arbitrary precision.
I<Usage>
$boolean = is_int($string);
$boolean = is_int('1'); # true
$boolean = is_int('-1'); # true
$boolean = is_int('1.0'); # false
$boolean = is_int(undef); # false
I<Arguments>
=over 4
=item C<$string>
=back
I<Returns>
=over 4
=item C<$boolean>
=back
I<Note>
=over 4
=item This function is also available as C<is_integer()>
=back
=head2 is_int8
Determine whether C<$string> is a 8-bit signed integer which can have any
value in the range -128 to 127.
I<Usage>
$boolean = is_int8($string);
$boolean = is_int8('-128'); # true
$boolean = is_int8('127'); # true
$boolean = is_int8(undef); # false
I<Arguments>
=over 4
=item C<$string>
=back
I<Returns>
=over 4
=item C<$boolean>
=back
=head2 is_int16
Determine whether C<$string> is a 16-bit signed integer which can have any
value in the range -32,768 to 32,767.
I<Usage>
$boolean = is_int16($string);
$boolean = is_int16('-32768'); # true
$boolean = is_int16('32767'); # true
$boolean = is_int16(undef); # false
I<Arguments>
=over 4
=item C<$string>
=back
I<Returns>
=over 4
=item C<$boolean>
=back
=head2 is_int32
Determine whether C<$string> is a 32-bit signed integer which can have any
value in the range -2,147,483,648 to 2,147,483,647.
I<Usage>
$boolean = is_int32($string);
$boolean = is_int32('-2147483648'); # true
$boolean = is_int32('2147483647'); # true
$boolean = is_int32(undef); # false
I<Arguments>
=over 4
=item C<$string>
=back
I<Returns>
=over 4
=item C<$boolean>
=back
=head2 is_int64
Determine whether C<$string> is a 64-bit signed integer which can have any
value in the range -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.
I<Usage>
$boolean = is_int64($string);
$boolean = is_int64('-9223372036854775808'); # true
$boolean = is_int64('9223372036854775807'); # true
$boolean = is_int64(undef); # false
I<Arguments>
=over 4
=item C<$string>
=back
I<Returns>
=over 4
=item C<$boolean>
=back
=head2 is_int128
Determine whether C<$string> is a 128-bit signed integer which can have any
value in the range -170,141,183,460,469,231,731,687,303,715,884,105,728 to
170,141,183,460,469,231,731,687,303,715,884,105,727.
I<Usage>
$boolean = is_int128($string);
$boolean = is_int128('-170141183460469231731687303715884105728'); # true
$boolean = is_int128('170141183460469231731687303715884105727'); # true
$boolean = is_int128(undef); # false
I<Arguments>
=over 4
=item C<$string>
=back
I<Returns>
=over 4
=item C<$boolean>
=back
=head2 is_uint
Determine whether C<$string> is an unsigned integer of arbitrary precision.
I<Usage>
$boolean = is_uint($string);
$boolean = is_uint('1'); # true
$boolean = is_uint('-1'); # false
$boolean = is_uint('1.0'); # false
$boolean = is_uint(undef); # false
I<Arguments>
=over 4
=item C<$string>
=back
I<Returns>
=over 4
=item C<$boolean>
=back
=head2 is_uint8
Determine whether C<$string> is a 8-bit unsigned integer which can have any
value in the range 0 to 255.
I<Usage>
$boolean = is_uint8($string);
$boolean = is_uint8('0'); # true
$boolean = is_uint8('255'); # true
$boolean = is_uint8(undef); # false
I<Arguments>
=over 4
=item C<$string>
=back
I<Returns>
=over 4
=item C<$boolean>
=back
=head2 is_uint16
Determine whether C<$string> is a 16-bit unsigned integer which can have any
value in the range 0 to 65,535.
I<Usage>
$boolean = is_uint16($string);
$boolean = is_uint16('0'); # true
$boolean = is_uint16('65535'); # true
$boolean = is_uint16(undef); # false
I<Arguments>
=over 4
=item C<$string>
=back
I<Returns>
=over 4
=item C<$boolean>
=back
=head2 is_uint32
Determine whether C<$string> is a 32-bit unsigned integer which can have any
value in the range 0 to 4,294,967,295.
I<Usage>
$boolean = is_uint32($string);
$boolean = is_uint32('0'); # true
$boolean = is_uint32('4294967295'); # true
$boolean = is_uint32(undef); # false
I<Arguments>
=over 4
=item C<$string>
=back
I<Returns>
=over 4
=item C<$boolean>
=back
=head2 is_uint64
Determine whether C<$string> is a 64-bit unsigned integer which can have any
value in the range 0 to 18,446,744,073,709,551,615.
I<Usage>
$boolean = is_uint64($string);
$boolean = is_uint64('0'); # true
$boolean = is_uint64('18446744073709551615'); # true
$boolean = is_uint64(undef); # false
I<Arguments>
=over 4
=item C<$string>
=back
I<Returns>
=over 4
=item C<$boolean>
=back
=head2 is_uint128
Determine whether C<$string> is a 128-bit unsigned integer which can have any
value in the range 0 to 340,282,366,920,938,463,463,374,607,431,768,211,455.
I<Usage>
$boolean = is_uint128($string);
$boolean = is_uint128('0'); # true
$boolean = is_uint128('340282366920938463463374607431768211455'); # true
$boolean = is_uint128(undef); # false
I<Arguments>
=over 4
=item C<$string>
=back
I<Returns>
=over 4
=item C<$boolean>
=back
=head1 LIMITATIONS
C<String::Numeric> supports numbers in decimal notation using Western Arabic
numerals and decimal fractions seperated with a dot. Other notations or numeral
systems are not supported.
=head1 COMPARISON
=head2 Scalar::Util
B<None> of the following is considered valid by C<String::Numeric>.
=over 4
=item * Fractional number without integer part or fractional part
looks_like_number("1.") # true
looks_like_number(".1") # true
=item * Plus prefix
looks_like_number("+1") # true
=item * Leading zeros
looks_like_number("01") # true
=item * Radix point other than C<.>
looks_like_number("1,1") # true assuming locale is in effect and locale radix point is ','
=item * Leading and/or trailing whitespace, such as HT, LF, FF, CR, and SP
looks_like_number("\n1") # true
looks_like_number("1\n") # true
looks_like_number("\n1\n") # true
=item * Numeric values that are not represented as a sequence of digits, such as
C<Inf>, C<Infinity>, C<NaN> and C<0 but true>
looks_like_number("Inf") # true
looks_like_number("Infinity") # true
looks_like_number("NaN") # true
looks_like_number("0 but true") # true
=back
=head1 GRAMMAR
=head2 String::Numeric ABNF
; String::Numeric ABNF Grammar
is-float = [ "-" ] FloatNumber
is-decimal = [ "-" ] DecimalNumber
is-integer = [ "-" ] DecimalInteger
is-uint = DecimalInteger
FloatNumber = DecimalNumber [ ExponentPart ]
DecimalNumber = DecimalInteger [ FractionalPart ]
DecimalInteger = "0" / ( NonZeroDigit *DecimalDigit )
DecimalDigit = %x30-39; 0-9
NonZeroDigit = %x31-39; 1-9
FractionalPart = "." 1*DecimalDigit
ExponentIndicator = "e" / "E"
ExponentPart = ExponentIndicator [ "+" / "-" ] 1*DecimalDigit
=head2 looks_like_number ABNF
; ABNF Grammar based on 5.10 Perl_grok_number()
looks-like-number = Number / ZeroButTrue
Number = *WS [ Sign ] ( FloatNumber / ( Infinity / NaN ) ) *WS;
FloatNumber = DecimalNumber [ ExponentPart ]
DecimalNumber = DecimalInteger [ "." *DecimalDigit ] / "." 1*DecimalDigit
DecimalInteger = 1*DecimalDigit
WS = %x09 ; HT
/ %x0A ; LF
/ %x0C ; FF
/ %x0D ; CR
/ %x20 ; SP
DecimalDigit = %x30-39; 0-9
Sign = "+" / "-"
ExponentIndicator = "e" / "E"
ExponentPart = ExponentIndicator [ Sign ] 1*DecimalDigit
Infinity = "Inf" / "Infinity"
NaN = "NaN"
ZeroButTrue = %x30.20.62.75.74.20.74.72.75.65 ; 0 but true
=head1 EXPORTS
None by default. Functions and constants can either be imported individually or
in sets grouped by tag names. The tag names are:
=over 4
=item C<:all> exports all functions.
=item C<:is_int> exports all C<is_int> functions.
=item C<:is_uint> exports all C<is_uint> functions.
=back
=head1 DIAGNOSTICS
=over 4
=item B<(F)> Usage: %s(string)
Subroutine %s invoked with wrong number of arguments.
=back
=head1 ENVIRONMENT
Set the environment variable C<STRING_NUMERIC_PP> to a true value before loading this package to disable usage of XS implementation.
=head1 PREREQUISITES
=head2 Run-Time
=over 4
=item L<perl> 5.006 or greater.
=item L<Carp>, core module.
=item L<Exporter>, core module.
=back
=head2 Build-Time
In addition to Run-Time:
=over 4
=item L<Test::More> 0.47 or greater, core module since 5.6.2.
=item L<Test::Exception>.
=back
=head1 SEE ALSO
L<String::Numeric::XS>
L<Data::Types>
L<Regexp::Common::number>
L<Scalar::Util>
L<Scalar::Util::Numeric>
=head1 AUTHOR
Christian Hansen C<chansen@cpan.org>
=head1 COPYRIGHT AND LICENSE
Copyright 2009 Christian Hansen.
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=cut