$bool
= is_eq(
$str
);
Returns true
if
the value perl assigns to an NV from the string
$str
is equal to the value C assigns to the C type specified by
$Config
{nvtype} from the same string.
Else returns false - which implies that either perl or C is buggy
in its assignment of that value. (Or they could both be buggy.)
When is_eq() returns false, the 2 differing
values
are by
default
printed to STDOUT (in
hex
). To disable this behaviour
set
$Math::NV::no_warn
to 2.
$ternary
= is_inexact(
$str
);
If
$ternary
is 0, then the value specified by
$str
is exactly
representable by an NV.
If
$ternary
is less than 0, then the value specified by
$str
is not exactly representable by an NV, and the nearest NV (ties
to even) is less than the value that the string specifies.
If
$ternary
is greater than 0, then the value specified by
$str
is not exactly representable by an NV, and the nearest NV (ties
to even) is greater than the value that the string specifies.
$bool
= is_eq_mpfr(
$str
);
Returns true
if
the value perl assigns from the string
$str
is
equal to the value mpfr assigns from the same string. If the
string represents a subnormal value then the mpfr value is
subnormalised
before
the comparison is made.
When is_eq_mpfr() returns false, the 2 differing
values
are by
default
printed to STDOUT (in
hex
). To disable this behaviour
set
$Math::NV::no_warn
to 2.
$nv
= nv(
$str
);
(
$nv
,
$iv
) = nv(
$str
);
On perls whose NV is a C
"double"
, assigns to
$nv
the value that
the C standard library function strtod(
$str
) assigns.
On perls whose NV is a C
"long double"
, assigns to
$nv
the value
that the C standard library function strtold(
$str
) assigns.
On perls whose NV is a C
"__float128"
, assigns to
$nv
the value
that the C standard library function strtofloat128(
$str
) assigns.
In list context, also returns the number of characters that were
unparsed (ignored).
Generally you'll want
$str
to be a string - eg the string
"2.3"
,
rather than the NV 2.3. Failure to adhere to this will result in
a warning - though you can disable this warning by setting
$Math::NV::no_warn
to 1.
$nv
= set_C(
$str
);
Uses the standard C library's strtod() or strtold() or strtoflt128(),
depending upon which of those three is correct
for
perl's floating
point type.
Expect the returned value to be the same as that returned by nv().
$nv
= set_mpfr(
$str
);
Uses Math::MPFR to assign the value specified by
$str
to the NV
$nv
.
Rounding is to nearest, ties to even.
If the string represents a subnormal value, then the value held by
the Math::MPFR object is subnormalized
before
being returned in
$nv
.
$hex
= nv_mpfr(
$str
, [
$bits
]);
Again,
values
will be subnormalized
if
appropriate.
If
$bits
is not specified, it will be set to the value returned by
mant_dig() - which is the appropriate value
for
the current perl
that is being run.
Valid
values
for
$bits
are 53 (double), 64 (80-bit extended
precision long double), 113 (128-bit quad long double or __float128).
To signify the double-double type, set
$bits
to either 106 or 2098.
(While the double-double
has
only 106 mantissa bits, it can
encapsulate precisions up to 2098 bits
for
some
values
. It makes
no
difference whether you specify 106 or 2098 - just go
with
the number
you consider to be the more appropriate or easiest to memorise.)
Any
values
other than 53, 64, 106, 113, or 2098 will cause an error.
Uses the mpfr library to assign the value represented by
$str
as a
double or long double or double-double or __float128 (as determined
by the value of
$bits
). It then returns a
hex
dump
of the bytes that
make up that C data type.
For example, nv_mpfr(
'1e+127'
, 53) returns 5a4d8ba7f519c84f.
This is the same as will be returned by
unpack
(
"H*"
,
pack
(
"d>"
, 1e+127))
if
the assignment of 1e+127 to a double
has
been done correctly.
For the double-double, the returned
scalar
is a reference to a list
that contains 2 elements - the
hex
dump
of the most significant
double, and the
hex
dump
of the least siginificant double.
For all other types, the returned
scalar
contains the
hex
dump
of the
given
value.
The enticement to
use
this function in preference to nv()/set_C is
twofold:
1) mpfr reliably sets floating point
values
correctly (whereas C is
more likely to suffer bugs);
2) nv_mpfr() can provide
hex
dumps
for
any of the four data types
(double, long double, double-double and __float128), whereas nv()
returns only the value
for
whichever data type is specified by
$Config
{nvtype}.
Note, however, that
for
nv_mpfr() to
return
the
hex
form of the
__float128 type, the mpfr library (as used by Math::MPFR) needs to have
been built using the configure option --enable-float128, and this
configure option is only available
with
mpfr-4.0.0 or later - and is
not available
for
all architectures.
As is the case
with
nv(), you'll generally want
$str
to be a string.
For example, specify the string
"2.3"
, rather than the NV 2.3.
Failure to adhere to this will result in a warning - though you can
disable this warning by setting
$Math::NV::no_warn
to 1.
$nv_type
= nv_type();
Returns
"double"
,
"long double"
, or
"__float128"
depending upon
the way perl
has
been configured.
The expectation is that it returns the same as
$Config
{nvtype}.
(Please file a bug report
if
you find otherwise.)
$digits
= mant_dig();
Returns the number of bits the NV mantissa contains. This is
normally 53
if
nv_type() is double. For nv_type() of
'long double'
it can be either 64 (extended precision long double), 113 (quad
long double) or 106 (IBM double-double).
For nv_type() of
'__float128'
, mant_dig() will
return
113.
This function returns
no
other than one of those 4
values
.
IOW, expect mant_dig() to
return
the value of the float.h macro
DBL_MANT_DIG, LDBL_MANT_DIG, or FLT128_MANT_DIG depending upon
whichever is appropriate
for
perl's configuration.
(
$mantissa
,
$exponent
,
$precision
) = ld2binary(
$nv
);
Uses code taken from tests/tset_ld.c in the mpfr library source
and returns a base 2 representation of the value contained in the
NV
$nv
- irrespective of whether the NV type (
$Config
{nvtype}) is
double, long double or __float128.
$mantissa
is the mantissa (significand).
$exponent
is the exponent.
$precision
is the precision (in bits) of the mantissa - trailing
zero bits are not counted. For example:
@x
= ld2binary(2 ** 45);
will, upon investigation of the contents of
@x
, reveal that the
mantissa is 0.1, the exponent is 46, and the precision is 1.
(
$mantissa
,
$exponent
,
$precision
) = ld_str2binary(
$str
);
As
for
ld2binary, except that the argument is a string, not an NV:
@x
= ld_str2binary(
'35184372088832'
);
produces same result as doing:
@x
= ld2binary(2 ** 45);
$nv
= bin2val(
$mantissa
,
$exponent
,
$precision
);
Takes the
return
values
of ld_str2binary() or ld2binary() and
returns the original NV. (Doesn't work
if
the original NV is an inf
or a nan.)
Cprintf(
$fmt
,
$nv
);
Uses C's
printf
() function to
format
the NV
$nv
, according to the
formatting specified by the string
$fmt
.
$string
= Csprintf(
$fmt
,
$nv
,
$buffer_size
);
Uses C's
sprintf
() function to
format
the NV
$nv
, according to the
formatting specified by the string
$fmt
- and returns the result to
$string
. It's the responsibility of the
caller
to ensure that
$buffer_size
specifies a large enough number of characters to
accommodate C's
sprintf
formatting of
$nv
.
$ternary
= cmp_2(
$str1
,
$str2
);
The main purpose here is to be able to determine (eg) whether:
0x1.7ap4 == 0b0.10111101e5
or:
0x1.6a09e667f3bcc908p+0 == 0xb.504f333f9de6484p-3
The 2 args begin
with
an (optional) + or - sign, followed by
(case-insensitive)
'0b'
,
'0x'
,
'nan'
or
'inf'
. That is, they must
match: /^(\-|\+)?0b|^(\-|\+)?0x|^(\-|\+)?nan|^(\-|\+)?inf/i
The spaceship operator (<=>) is then used to compare the numeric
values
of the two strings, the result of which is returned.
A negative
return
indicates that
$str1
<
$str2
; a positive
return
indicates that
$str1
>
$str2
; a
return
of zero indicates that
$str1
==
$str2
; a
return
of
undef
indicates that
$str1
and/or
$str2
is a NaN.
The
values
of the 2 args are calculated to their full precisions,
even
if
either/both of those precisions exceed the precision of
perl's floating point type (NV).