NAME
Data::Float - details of the floating point data type
SYNOPSIS
use Data::Float qw(have_signed_zero);
if(have_signed_zero) { ...
# and many other constants; see text
use Data::Float qw(
float_class float_is_normal float_is_subnormal
float_is_nzfinite float_is_zero float_is_finite
float_is_infinite float_is_nan
);
$class = float_class($value);
if(float_is_normal($value)) { ...
if(float_is_subnormal($value)) { ...
if(float_is_nzfinite($value)) { ...
if(float_is_zero($value)) { ...
if(float_is_finite($value)) { ...
if(float_is_infinite($value)) { ...
if(float_is_nan($value)) { ...
use Data::Float qw(float_sign float_parts float_hex);
$sign = float_sign($value);
($sign, $exponent, $significand) = float_parts($value);
print float_hex($value);
use Data::Float qw(pow2 mult_pow2 copysign nextafter);
$x = pow2($exp);
$x = mult_pow2($value, $exp);
$x = copysign($value, $x);
$x = nextafter($value, $x);
DESCRIPTION
This module is about the native floating point numerical data type. A floating point number is one of the types of datum that can appear in the numeric part of a Perl scalar. This module supplies constants describing the native floating point type, classification functions, and functions to manipulate floating point values at a low level.
FLOATING POINT
Floating point values are divided into five subtypes:
- normalised
-
The value is made up of a sign bit (making the value positive or negative), a significand, and exponent. The significand is a number in the range [1, 2), expressed as a binary fraction of a certain fixed length. (Significands requiring a longer binary fraction, or lacking a terminating binary representation, cannot be obtained.) The exponent is an integer in a certain fixed range. The magnitude of the value represented is the product of the significand and two to the power of the exponent.
- subnormal
-
The value is made up of a sign bit, significand, and exponent, as for normalised values. However, the exponent is fixed at the minimum possible for a normalised value, and the significand is in the range (0, 1). The length of the significand is the same as for normalised values. This is essentially a fixed-point format, used to provide gradual underflow. Not all floating point formats support this subtype. Where it is not supported, underflow is sudden, and the difference between two minimum-exponent normalised values cannot be exactly represented.
- zero
-
Depending on the floating point type, there may be either one or two zero values: zeroes may carry a sign bit. Where zeroes are signed, it is primarily in order to indicate the direction from which a value underflowed (was rounded) to zero. Positive and negative zero compare as numerically equal, and they give identical results in most arithmetic operations. They are on opposite sides of some branch cuts in complex arithmetic.
Beware that as of Perl 5.8.7 Perl will lose the sign of a zero for some purposes if it is used in any arithmetic, including numerical comparisons. Stringification of a zero is inconsistent in whether it shows the sign.
- infinite
-
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
1.0/0.0
causes an exception rather than returning an infinity. - 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
0.0/0.0
causes an exception rather than returning a NaN.
CONSTANTS
Features
- have_signed_zero
-
Boolean indicating whether floating point zeroes carry a sign. If yes, then there are two zero values: +0.0 and -0.0. If no, then there is only one zero value, considered unsigned.
- have_subnormal
-
Boolean indicating whether there are subnormal floating point values.
- have_infinite
-
Boolean indicating whether there are infinite floating point values.
- have_nan
-
Boolean 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
nan
constant below.
Finite Extrema
- significand_bits
-
The number of fractional bits in the significand of finite floating point values.
- significand_step
-
The difference between adjacent representable values in the range [1, 2]. This is equal to 2^-significand_bits.
- max_finite_exp
-
The maximum exponent permitted for finite floating point values.
- max_finite_pow2
-
The maximum representable power of two. This is 2^max_finite_exp.
- max_finite
-
The maximum representable finite value. This is 2^(max_finite_exp+1) - 2^(max_finite_exp-significand_bits).
- max_integer
-
The maximum representable integral value. This is 2^(significand_bits+1) - 1.
- min_normal_exp
-
The minimum exponent permitted for normalised floating point values.
- min_normal
-
The minimum positive value representable as a normalised floating point value. This is 2^min_normal_exp.
- min_finite_exp
-
The base two logarithm of the minimum representable positive finite value. If there are subnormals then this is min_normal_exp - significand_bits. If there are no subnormals then this is min_normal_exp.
- min_finite
-
The minimum representable positive finite value. This is 2^min_finite_exp.
Special Values
- pos_zero
-
The positive zero value. (Exists only if zeroes are signed, as indicated by the
have_signed_zero
constant.) - neg_zero
-
The negative zero value. (Exists only if zeroes are signed, as indicated by the
have_signed_zero
constant.) - pos_infinity
-
The positive infinite value. (Exists only if there are infinite values, as indicated by the
have_infinite
constant.) - neg_infinity
-
The negative infinite value. (Exists only if there are infinite values, as indicated by the
have_infinite
constant.) - nan
-
Not-a-number. (Exists only if NaN values were detected, as indicated by the
have_nan
constant.)
FUNCTIONS
Each "float_" function takes a floating point argument to operate on. The argument must be a native floating point value, or a native integer (which will be silently converted to floating point). Giving a non-numeric argument will cause mayhem. See "is_number" in Params::Classify for a way to check for numericness.
Classification
Each "float_is_" function returns a simple boolean result.
- float_class(VALUE)
-
Determines which of the five classes described above VALUE falls into. Returns "NORMAL", "SUBNORMAL", "ZERO", "INFINITE", or "NAN" accordingly.
- float_is_normal(VALUE)
-
Returns true iff VALUE is a normalised floating point value.
- float_is_subnormal(VALUE)
-
Returns true iff VALUE is a subnormal floating point value.
- float_is_nzfinite(VALUE)
-
Returns true iff VALUE is a non-zero finite value (either normal or subnormal; not zero, infinite, or NaN).
- float_is_zero(VALUE)
-
Returns true iff VALUE is a zero. If zeroes are signed then both signs qualify.
- float_is_finite(VALUE)
-
Returns true iff VALUE is a finite value (either normal, subnormal, or zero; not infinite or NaN).
- float_is_infinite(VALUE)
-
Returns true iff VALUE is an infinity (either positive infinity or negative infinity).
- float_is_nan(VALUE)
-
Returns true iff VALUE is a NaN.
Examination
- float_sign(VALUE)
-
Returns "+" or "-" to indicate the sign of VALUE. If zero is unsigned then it is treated as positive.
die
s if VALUE is a NaN. - float_parts(VALUE)
-
Divides up a non-zero finite floating point value into sign, exponent, and significand, returning these as a three-element list in that order. The significand is returned as a floating point value, in the range [1, 2) for normalised values, and in the range (0, 1) for subnormals.
die
s if VALUE is not finite and non-zero. - float_hex(VALUE)
-
Encodes the exact value of VALUE as a hexadecimal fraction, returning the fraction as a string. Specifically, for finite values the output is of the form "s0xm.fffffpeee", where "s" is the sign, "m" is the integral part of the significand ("1" for normals and "0" for subnormals), "fffff" is the fractional part of the significand in hexadecimal, and "eee" is the exponent in decimal with a sign. The number of significand fraction digits is constant, being just sufficient to represent all the bits of the significand.
Zeros are encoded as "+0.0" and "-0.0", with the same unreliability noted above for
float_sign
. If zero is unsigned then it is encoded as "+0.0". Infinities are encoded as "+inf" and "-inf". NaNs are encoded as "nan".
Manipulation
- pow2(EXP)
-
EXP must be an integer. Returns the value two the the power EXP.
die
s if that value cannot be represented exactly as a floating point value. The return value may be either normalised or subnormal. - mult_pow2(VALUE, EXP)
-
EXP must be an integer, and VALUE a floating point value. Multiplies 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.
- 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 function
die
s. - nextafter(VALUE, DIRECTION)
-
Returns the next representable floating point value adjacent to VALUE in the direction of DIRECTION. Returns a NaN if either argument is a NaN, and returns VALUE unchanged if it is numerically equal to DIRECTION. 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.
BUGS
Perl (as of version 5.8.7) doesn't reliably maintain the sign of a zero. The functions in this module all handle the sign of a zero correctly if it is present, but they can't rescue the sign if it has already been lost. Avoid relying on correct signed-zero handling, even if you know your hardware handles it correctly.
NaN handling is generally not well defined in Perl. Arithmetic with a mathematically undefined result may either die
or generate a NaN. Avoid relying on any particular behaviour for such operations, even if your hardware's behaviour is known.
AUTHOR
Andrew Main (Zefram) <zefram@fysh.org>
COPYRIGHT
Copyright (C) 2006 Andrew Main (Zefram) <zefram@fysh.org>
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.