view release on metacpan or search on metacpan
- in Build.PL, explicitly declare configure-time requirements
- remove bogus "exit 0" from Build.PL
- add MYMETA.yml to .cvsignore
v0.009 2008-04-06
- refer to optional constants more carefully in the code, to avoid
syntax problems on systems that lack infinities and NaNs
- fix a skip count that caused false test failures on systems lacking
signed zeroes
v0.008 2008-04-02
- bugfix: in initialisation, correctly override any ambient
$SIG{__DIE__}
v0.007 2007-10-02
- float_hex(): new option "hex_prefix_string" to control the "0x" prefix
- test classification functions, examination functions, string
conversion functions, and manipulation functions (all the functions
that were not being tested)
- test all functions for lack of side effects on zero arguments and
purity of zero results
- in documentation, note new standard-conforming behaviour of copysign()
with a NaN second argument
- in documentation, note that hex_float() accepts the special "0.0"
form of input without a sign, as well as with one
- in documentation, where the IEEE standard nature of functions is
noted, add discussion of non-conforming behaviour on NaNs
- in documentation, change some variable names in the synopsis for
clarity
- test POD syntax and coverage, and rename some internal functions to
satisfy the coverage test
- tweak tests on constants to avoid infinite loops if importing constant
functions fails
- build with Module::Build instead of ExtUtils::MakeMaker
- complete dependency list
- include signature in distribution
- in documentation, separate "license" section from "copyright" section
v0.005 2007-01-25
- bugfix: change behaviour of copysign() with a NaN as the second
argument to that specified by IEEE 754: it is not an error but
(in the context of Perl's opaque NaNs) results in copying an
unpredictable sign
- add hex_float() function to input floating point values in hexadecimal
- add IEEE 754 function signbit()
- float_id_cmp(): tighten specification of return values to match
Perl's <=> operator (actual behaviour always matched the tighter spec,
it just wasn't documented and tested)
- in documentation, note that both arguments to nextafter() must be
floating point values
- in documentation, note standard nature of signbit(), copysign(),
and nextafter()
- in documentation, note float_id_cmp()'s relation to the IEEE 754r
function totalorder()
- in documentation, note that Perl does not distinguish between
different NaNs
- in documentation, give a second definition of max_integer (equivalent
to the first)
- add test for consistency of constants
- in documentation, reference Scalar::Number
- remove now-useless test t/use.t
- in documentation, note the slightly misleading nature of the names
"significand_bits" and "max_integer"
- reference Data::Integer and perlnumber(1) in documentation
v0.003 2006-08-08
- float_hex(): add OPTIONS parameter to control details of output
formatting
- when looking for NaNs, see whether the string "nan" qualifies
- slight clarification to documentation of significand_step
v0.002 2006-08-03
- bugfix: in mult_pow2(), copysign(), and nextafter(), take care
to return a pristine signed zero when returning zero: they were
returning zeroes that got broken (due to the Perl bug noted in the
documentation) by internal arithmetic
lib/Data/Float.pm view on Meta::CPAN
Some floating point formats include special infinite values. These are
generated by overflow, and by some arithmetic cases that mathematically
generate infinities. There are two infinite values: positive infinity
and negative infinity.
Perl does not always generate infinite values when normal floating point
behaviour calls for it. For example, the division C<1.0/0.0> causes an
exception rather than returning an infinity.
=item not-a-number (NaN)
This type of value exists in some floating point formats to indicate
error conditions. Mathematically undefined operations may generate NaNs,
and NaNs propagate through all arithmetic operations. A NaN has the
distinctive property of comparing numerically unequal to all floating
point values, including itself.
Perl does not always generate NaNs when normal floating point behaviour
calls for it. For example, the division C<0.0/0.0> causes an exception
rather than returning a NaN.
Perl has only (at most) one NaN value, even if the underlying system
supports different NaNs. (IEEE 754 arithmetic has NaNs which carry a
quiet/signal bit, a sign bit (yes, a sign on a not-number), and many
bits of implementation-defined data.)
=back
=head2 Mixing floating point and integer values
Perl does not draw a strong type distinction between native integer
(see L<Data::Integer>) and native floating point values. Both types
of value can be stored in the numeric part of a plain (string) scalar.
lib/Data/Float.pm view on Meta::CPAN
=item have_subnormal
Truth value indicating whether there are subnormal floating point values.
=item have_infinite
Truth value indicating whether there are infinite floating point values.
=item have_nan
Truth value indicating whether there are NaN floating point values.
It is difficult to reliably generate a NaN in Perl, so in some unlikely
circumstances it is possible that there might be NaNs that this module
failed to detect. In that case this constant would be false but a NaN
might still turn up somewhere. What this constant reliably indicates
is the availability of the C<nan> constant below.
=back
=head2 Extrema
=over
=item significand_bits
lib/Data/Float.pm view on Meta::CPAN
The positive infinite value. (Exists only if there are infinite values,
as indicated by the C<have_infinite> constant.)
=item neg_infinity
The negative infinite value. (Exists only if there are infinite values,
as indicated by the C<have_infinite> constant.)
=item nan
Not-a-number. (Exists only if NaN values were detected, as indicated
by the C<have_nan> constant.)
=back
=cut
sub _mk_constant($$) {
my($name, $value) = @_;
no strict "refs";
*{__PACKAGE__."::".$name} = sub () { $value };
lib/Data/Float.pm view on Meta::CPAN
Returns true iff VALUE is a subnormal floating point value.
=cut
sub float_is_subnormal($) { float_class($_[0]) eq "SUBNORMAL" }
=item float_is_nzfinite(VALUE)
Returns true iff VALUE is a non-zero finite value (either normal or
subnormal; not zero, infinite, or NaN).
=cut
sub float_is_infinite($);
sub float_is_nzfinite($) {
my($val) = @_;
return $val != 0.0 && $val == $val && !float_is_infinite($val);
}
lib/Data/Float.pm view on Meta::CPAN
=cut
sub float_is_zero($) {
my($val) = @_;
return $val == 0.0;
}
=item float_is_finite(VALUE)
Returns true iff VALUE is a finite value (either normal, subnormal,
or zero; not infinite or NaN).
=cut
sub float_is_finite($) {
my($val) = @_;
return $val == $val && !float_is_infinite($val);
}
=item float_is_infinite(VALUE)
lib/Data/Float.pm view on Meta::CPAN
=cut
sub float_is_infinite($) {
return undef unless have_infinite;
my($val) = @_;
return $val == $pos_infinity || $val == $neg_infinity;
}
=item float_is_nan(VALUE)
Returns true iff VALUE is a NaN.
=cut
sub float_is_nan($) {
my($val) = @_;
return $val != $val;
}
=back
=head2 Examination
=over
=item float_sign(VALUE)
Returns "B<+>" or "B<->" to indicate the sign of VALUE. An unsigned
zero returns the sign "B<+>". C<die>s if VALUE is a NaN.
=cut
sub signbit($);
sub float_sign($) {
my($val) = @_;
croak "can't get sign of a NaN" if $val != $val;
return signbit($val) ? "-" : "+";
}
=item signbit(VALUE)
VALUE must be a floating point value. Returns the sign bit of VALUE:
0 if VALUE is positive or a positive or unsigned zero, or 1 if VALUE is
negative or a negative zero. Returns an unpredictable value if VALUE
is a NaN.
This is an IEEE 754 standard function. According to the standard NaNs
have a well-behaved sign bit, but Perl can't see that bit.
=cut
sub signbit($) {
my($val) = @_;
return (have_signed_zero && $val == 0.0 ?
sprintf("%+.f", $val) eq "-0" : $val < 0.0) ? 1 : 0;
}
lib/Data/Float.pm view on Meta::CPAN
The string that is prefixed to hexadecimal digits. Default "B<0x>".
Make it the empty string to suppress the prefix.
=item B<infinite_string>
The string that is returned for an infinite magnitude. Default "B<inf>".
=item B<nan_string>
The string that is returned for a NaN value. Default "B<nan>".
=item B<neg_sign>
The string that is prepended to a negative value (including negative
zero). Default "B<->".
=item B<pos_sign>
The string that is prepended to a positive value (including positive or
unsigned zero). Default "B<+>". Make it the empty string to suppress
lib/Data/Float.pm view on Meta::CPAN
If the value given in the string cannot be exactly represented in the
floating point type because it has too many fraction bits, the nearest
representable value is returned, with ties broken in favour of the value
with a zero low-order bit. If the value given is too large to exactly
represent then an infinity is returned, or the largest finite value if
there are no infinities.
Additional input formats are accepted for special values.
"[I<s>]B<inf>[B<inity>]" returns an infinity, or C<die>s if there are
no infinities. "[I<s>][B<s>]B<nan>" returns a NaN, or C<die>s if there
are no NaNs available.
All input formats are understood case insensitively. The function
correctly interprets all possible outputs from C<float_hex> with default
settings.
=cut
sub hex_float($) {
my($str) = @_;
if($str =~ /\A([-+]?)(?:0x)?([0-9a-f]+)(?:\.([0-9a-f]+)+)?
lib/Data/Float.pm view on Meta::CPAN
=item float_id_cmp(A, B)
This is a comparison function supplying a total ordering of floating
point values. A and B must both be floating point values. Returns -1,
0, or +1, indicating whether A is to be sorted before, the same as,
or after B.
The ordering is of the identities of floating point values, not their
numerical values. If zeroes are signed, then the two types are considered
to be distinct. NaNs compare equal to each other, but different from
all numeric values. The exact ordering provided is mostly numerical
order: NaNs come first, followed by negative infinity, then negative
finite values, then negative zero, then positive (or unsigned) zero,
then positive finite values, then positive infinity.
In addition to sorting, this function can be useful to check for a zero
of a particular sign.
=cut
sub float_id_cmp($$) {
my($a, $b) = @_;
lib/Data/Float.pm view on Meta::CPAN
return $a <=> $b;
}
}
=item totalorder(A, B)
This is a comparison function supplying a total ordering of floating point
values. A and B must both be floating point values. Returns a truth value
indicating whether A is to be sorted before-or-the-same-as B. That is,
it is a <= predicate on the total ordering. The ordering is the same as
that provided by C<float_id_cmp>: NaNs come first, followed by negative
infinity, then negative finite values, then negative zero, then positive
(or unsigned) zero, then positive finite values, then positive infinity.
This is an IEEE 754r standard function. According to the standard it
is meant to distinguish different kinds of NaNs, based on their sign
bit, quietness, and payload, but this function (like the rest of Perl)
perceives only one NaN.
=cut
sub totalorder($$) { float_id_cmp($_[0], $_[1]) <= 0 }
=back
=head2 Manipulation
=over
lib/Data/Float.pm view on Meta::CPAN
VALUE by two to the power EXP. This gives exact results, except in
cases of underflow and overflow. The range of EXP is not constrained.
All normal floating point multiplication behaviour applies.
=item copysign(VALUE, SIGN_FROM)
VALUE and SIGN_FROM must both be floating point values. Returns a
floating point value with the magnitude of VALUE and the sign of
SIGN_FROM. If SIGN_FROM is an unsigned zero then it is treated as
positive. If VALUE is an unsigned zero then it is returned unchanged.
If VALUE is a NaN then it is returned unchanged. If SIGN_FROM is a NaN
then the sign copied to VALUE is unpredictable.
This is an IEEE 754 standard function. According to the standard NaNs
have a well-behaved sign bit, which can be read and modified by this
function, but Perl only perceives one NaN and can't see its sign bit,
so behaviour on NaNs is not standard-conforming.
=cut
sub copysign($$) {
my($val, $signfrom) = @_;
return $val if float_is_nan($val);
$val = -$val if signbit($val) != signbit($signfrom);
return $val;
}
=item nextup(VALUE)
VALUE must be a floating point value. Returns the next representable
floating point value adjacent to VALUE with a numerical value that is
strictly greater than VALUE, or returns VALUE unchanged if there is
no such value. Infinite values are regarded as being adjacent to the
largest representable finite values. Zero counts as one value, even if
it is signed, and it is adjacent to the smallest representable positive
and negative finite values. If a zero is returned, because VALUE is
the smallest representable negative value, and zeroes are signed, it is
a negative zero that is returned. Returns NaN if VALUE is a NaN.
This is an IEEE 754r standard function.
=cut
sub nextup($) {
my($val) = @_;
return $val if $val != $val || $val == max_number;
return -(max_finite) if have_infinite && $val == -(max_number);
return min_finite if $val == 0.0;
lib/Data/Float.pm view on Meta::CPAN
=item nextdown(VALUE)
VALUE must be a floating point value. Returns the next representable
floating point value adjacent to VALUE with a numerical value that
is strictly less than VALUE, or returns VALUE unchanged if there is
no such value. Infinite values are regarded as being adjacent to the
largest representable finite values. Zero counts as one value, even if
it is signed, and it is adjacent to the smallest representable positive
and negative finite values. If a zero is returned, because VALUE is
the smallest representable positive value, and zeroes are signed, it is
a positive zero that is returned. Returns NaN if VALUE is a NaN.
This is an IEEE 754r standard function.
=cut
sub nextdown($) { -nextup(-(my $n = $_[0])) }
=item nextafter(VALUE, DIRECTION)
VALUE and DIRECTION must both be floating point values. Returns the
next representable floating point value adjacent to VALUE in the
direction of DIRECTION, or returns DIRECTION if it is numerically
equal to VALUE. Infinite values are regarded as being adjacent to
the largest representable finite values. Zero counts as one value,
even if it is signed, and it is adjacent to the positive and negative
smallest representable finite values. If a zero is returned and zeroes
are signed then it has the same sign as VALUE. Returns NaN if either
argument is a NaN.
This is an IEEE 754 standard function.
=cut
sub nextafter($$) {
my($val, $dir) = @_;
return $_[1] if $dir != $dir || $val == $dir;
return $dir > $val ? nextup($_[0]) : nextdown($_[0]);
}
lib/Data/Float.pm view on Meta::CPAN
return a pristine one.
As of Perl 5.8.7 stringification of a floating point zero does not
preserve its signedness. The number-to-string-to-number round trip
turns a positive floating point zero into an integer zero, but accurately
maintains negative and integer zeroes. If a negative zero gets partially
transformed into an integer zero, as described above, the stringification
that it gets is based on its state at the first occasion on which the
scalar was stringified.
NaN handling is generally not well defined in Perl. Arithmetic with
a mathematically undefined result may either C<die> or generate a NaN.
Avoid relying on any particular behaviour for such operations, even if
your hardware's behaviour is known.
As of Perl 5.8.7 the B<%> operator truncates its arguments to integers, if
the divisor is within the range of the native integer type. It therefore
operates correctly on non-integer values only when the divisor is
very large.
=head1 SEE ALSO
ok &{"Data::Float::pos_infinity"} > max_finite;
ok &{"Data::Float::neg_infinity"} < -max_finite();
ok max_number == &{"Data::Float::pos_infinity"};
ok max_number > max_finite;
} else {
SKIP: { skip "no infinities", 3; }
ok max_number == max_finite;
}
SKIP: {
skip "no NaNs", 1 unless have_nan;
no strict "refs";
my $nan = &{"Data::Float::nan"};
ok $nan != $nan;
}
1;
t/copysign.t view on Meta::CPAN
ok copysign($ninf, +5) == $pinf;
ok copysign($pinf, -5) == $ninf;
ok copysign($ninf, -5) == $ninf;
ok copysign(+1.2, $pinf) == +1.2;
ok copysign(-1.2, $pinf) == +1.2;
ok copysign(+1.2, $ninf) == -1.2;
ok copysign(-1.2, $ninf) == -1.2;
}
SKIP: {
skip "NaN not available", 3 unless have_nan;
no strict "refs";
my $nan = &{"Data::Float::nan"};
ok float_is_nan(copysign($nan, +5));
ok float_is_nan(copysign($nan, $nan));
ok abs(copysign(+1.2, $nan)) == 1.2;
}
1;
ok hex_float("iNfiniTy") == $pinf;
ok hex_float("+infinity") == $pinf;
ok hex_float("+Infinity") == $pinf;
ok hex_float("+iNfiniTy") == $pinf;
ok hex_float("-infinity") == $ninf;
ok hex_float("-Infinity") == $ninf;
ok hex_float("-iNfiniTy") == $ninf;
}
SKIP: {
skip "no NaN", 20 unless have_nan;
no strict "refs";
is float_hex(&{"Data::Float::nan"}), "nan";
is float_hex(&{"Data::Float::nan"}, \%str_opt), "(NAN)";
ok float_is_nan(hex_float("nan"));
ok float_is_nan(hex_float("Nan"));
ok float_is_nan(hex_float("nAn"));
ok float_is_nan(hex_float("+nan"));
ok float_is_nan(hex_float("+Nan"));
ok float_is_nan(hex_float("+nAn"));
ok float_is_nan(hex_float("-nan"));
t/nextafter.t view on Meta::CPAN
ok nextafter(+max_finite(), $pinf) == $pinf;
ok nextdown( -max_finite()) == $ninf;
ok nextafter(-max_finite(), $ninf) == $ninf;
ok nextup( $ninf) == -max_finite();
ok nextafter($ninf, $pinf) == -max_finite();
ok nextdown( $pinf) == +max_finite();
ok nextafter($pinf, $ninf) == +max_finite();
}
SKIP: {
skip "NaN not available", 5 unless have_nan;
no strict "refs";
my $nan = &{"Data::Float::nan"};
ok float_is_nan(nextup($nan));
ok float_is_nan(nextdown($nan));
ok float_is_nan(nextafter($nan, +9));
ok float_is_nan(nextafter(+1.2, $nan));
ok float_is_nan(nextafter($nan, $nan));
}
1;