Data::Float::DoubleDouble - human-friendly representation of the "double-double" long double
Mostly, one would use Data::Float to do what this module does. But that module doesn't work with the powerpc long double, which uses a 'double-double' arrangement ... hence, this module. Given a double-double value, we aim to be able to: 1) Convert that NV to its internal packed hex form; 2) Convert the packed hex form of 1) back to the original value; 3) Convert that NV to a more human-readable packed hex form, similar to what Data::Float's float_hex function achieves; 4) Convert the packed hex form of 3) back to the original value; For 1) we use NV2H(). For 2) we use H2NV(). For 3) we use float_H(). For 4) we use H_float().
############################################# $hex = NV2H($nv); Unpacks the NV to a string of 32 hex characters. The first 16 characters relate to the value of the most significant double: Characters 1 to 3 (incl) embody the sign of the mantissa, the value of the exponent, and the value (0 or 1) of the implied leading bit. Characters 4 to 16 (incl) embody the value of the 52-bit mantissa. The second 16 characters (17 to 32) relate to the value of the least siginificant double: Characters 17 to 19 (incl) embody the sign of the mantissa, the value of the exponent, and the value (0 or 1) of the implied leading bit. Characters 20 to 32 (incl) embody the value of the 52-bit mantissa. For a more human-readable hex representation, use float_H(). ############################################# $nv = H2NV($hex); For $hex written in the format returned by NV2H, H2NV($hex) returns the NV. ############################################# $hex = D2H($nv); Treats the NV as a double and returns a string of 16 hex characters. Characters 1 to 3 (incl) embody the sign of the mantissa, the value (0 or 1) of the implied leading bit and the value of the exponent. Characters 4 to 16 (incl) embody the value of the 52-bit mantissa of the first double. ############################################# $nv = H2D($hex); For $hex written in the format returned by D2H, H2D($hex) returns the NV. ############################################# $readable_hex = float_H($nv); # Aliased to float_hex For *most* NVs, returns a 106-bit hex representation of the NV (long double) $nv in the format s0xd.hhhhhhhhhhhhhhhhhhhhhhhhhhhpe where: s is the sign (either '-' or '+') 0x is literally "0x" d is the leading (first) bit of the number (either '1' or '0') . is literally "." (the decimal point) hhhhhhhhhhhhhhhhhhhhhhhhhhh is a string of 27 hex digits representing the remaining 105 bits of the mantissa. p is a literal "p" that separates mantissa from exponent e is the (signed) exponent The keen mind will have realised that 27 hex digits encode 108 (not 105) bits. However, the last 3 bits are to be ignored and will always be zero for a 106-bit float. Thus the 27th hex character for a 106-bit float will either be "8" (representing a "1") or "0" (representing a "0") for the 106th bit. BUT: Some NV values encapsulate a value that require more than 106 bits in order to be correctly represented. If the string that float_H returns is larger than as described above, then it will, however, have returned a string that contains the *minimum* number of characters needed to accurately represent the given value. As an extreme example: the double-double arrangement can represent the value 2**1023 + 2**-1074, but to express that value as a stream of bits requires 2098 bits, and to express that value in the format that float_H returns requires 526 hex characters (all of which are zero, except for the first and the last). When you add the sign, radix point, exponent, etc., the float_H representation of that value consists of 535 characters. ############################################# $nv = H_float($hex); For $hex written in the format returned by float_H(), returns the NV that corresponds to $hex. ############################################# @bin = get_bin($nv); Returns the sign, the mantissa (as a base 2 string), and the exponent of $nv. (There's an implied radix point between the first and second digits of the mantissa). ############################################# @bin = float_H2B($hex); As for the above get_bin() function - but takes the hex string of the NV (as returned by float_H) as its argument, instead of the actual NV. For a more direct way of obtaining the array, use get_bin instead. ############################################# $hex = B2float_H(@bin); The reverse of float_H2B. It takes the array returned by either get_bin or float_H2B as its arguments, and returns the corresponding hex form. ############################################# ($sign1, $sign2) = get_sign($nv); Returns the signs of the two doubles contained in $nv. ############################################# ($exp1, $exp2) = get_exp($nv); Returns the exponents of the two doubles contained in $nv. ############################################# ($mantissa1, $mantissa2) = get_mant_H(NV2H($nv)); Returns an array of the two 52-bit mantissa components of the two doubles in their hex form. The values of the implied leading (most significant) bits are not provided, nor are the values of the two exponents. ############################################# $intermediate_zeroes = inter_zero(get_exp($nv)); Returns the number of zeroes that need to come between the mantissas of the 2 doubles when $nv is translated to the representation that float_H() returns. ############################################# $bool = are_inf(@nv); # Aliased to float_is_infinite. Returns true if and only if all of the (NV) arguments are infinities. Else returns false. ############################################# $bool = are_nan(@nv); # Aliased to float_is_nan. Returns true if and only if all of the (NV) arguments are NaNs. Else returns false. ############################################# For Compatibility with Data::Float: ############################################# $class = float_class($nv); Returns one of either "NAN", "INFINITE", "ZERO", "NORMAL" or "SUBNORMAL" - whichever is appropriate. (The NV must belong to one (and only one) class. ############################################# $bool = float_is_nan($nv); # Alias for are_nan() Returns true if $nv is a NaN. Else returns false. ############################################# $bool = float_is_infinite($nv); # Alias for are_inf() Returns true if $nv is infinite. Else returns false. ############################################# $bool = float_is_finite($nv); Returns true if NV is neither infinite nor a NaN. Else returns false. ############################################# $bool = float_is_nzfinite($nv); Returns true if NV is neither infinite, nor a NaN, nor zero. Else returns false. ############################################# $bool = float_is_zero($nv); Returns true if NV is zero. Else returns false. ############################################# $bool = float_is_normal($nv); Returns true if NV is finite && non-zero && the implied leading digit in its internal representation is '1'. Else returns false. ############################################# $bool = float_is_subnormal($nv); Returns true if NV is finite && non-zero && the implied leading digit in its internal representation is '0'. ############################################# ############################################# ############################################# ############################################# #############################################
Over time, introduce the features of (and functions provided by) Data::Float
This program is free software; you may redistribute it and/or modify it under the same terms as Perl itself. Copyright 2014 Sisyphus
Sisyphus <sisyphus at(@) cpan dot (.) org>
To install Data::Float::DoubleDouble, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Data::Float::DoubleDouble
CPAN shell
perl -MCPAN -e shell install Data::Float::DoubleDouble
For more information on module installation, please visit the detailed CPAN module installation guide.