2014-05-08 14:48:36 +02:00
|
|
|
.. _arf:
|
|
|
|
|
2014-05-27 20:14:09 +02:00
|
|
|
**arf.h** -- arbitrary-precision floating-point numbers
|
2014-05-08 14:48:36 +02:00
|
|
|
===============================================================================
|
|
|
|
|
2015-01-28 18:20:07 +01:00
|
|
|
A variable of type :type:`arf_t` holds an arbitrary-precision binary
|
|
|
|
floating-point number, i.e. a rational number of the form
|
|
|
|
`x \times 2^y` where `x, y \in \mathbb{Z}` and `x` is odd;
|
|
|
|
or one of the special values zero, plus infinity, minus infinity,
|
|
|
|
or NaN (not-a-number).
|
|
|
|
|
|
|
|
The *exponent* of a finite and nonzero floating-point number can be
|
|
|
|
defined in different
|
|
|
|
ways: for example, as the component *y* above, or as the unique
|
|
|
|
integer *e* such that
|
|
|
|
`x \times 2^y = m \times 2^e` where `1/2 \le |m| < 1`.
|
|
|
|
The internal representation of an :type:`arf_t` stores the
|
|
|
|
exponent in the latter format.
|
|
|
|
|
|
|
|
The conventions for special values largely follow those of the
|
|
|
|
IEEE floating-point standard. At the moment, there is no support
|
|
|
|
for negative zero, unsigned infinity, or a NaN with a payload, though
|
2015-11-23 11:14:14 -05:00
|
|
|
some of these might be added in the future.
|
2015-01-28 18:20:07 +01:00
|
|
|
|
|
|
|
Except where otherwise noted, the output of an operation is the
|
|
|
|
floating-point number obtained by taking the inputs as exact numbers,
|
|
|
|
in principle carrying out the operation exactly, and rounding the
|
|
|
|
resulting real number to the nearest representable floating-point
|
|
|
|
number whose mantissa has at most the specified number of bits, in
|
|
|
|
the specified direction of rounding. Some operations are always
|
|
|
|
or optionally done exactly.
|
|
|
|
|
|
|
|
The :type:`arf_t` type is almost identical semantically to
|
|
|
|
the legacy :type:`fmpr_t` type, but uses a more efficient
|
|
|
|
internal representation.
|
2014-05-27 20:14:09 +02:00
|
|
|
The most significant differences that the user
|
|
|
|
has to be aware of are:
|
|
|
|
|
|
|
|
* The mantissa is no longer represented as a FLINT :type:`fmpz`, and the
|
|
|
|
internal exponent points to the top of the binary expansion of the mantissa
|
|
|
|
instead of of the bottom. Code designed to manipulate components of an
|
|
|
|
:type:`fmpr_t` directly can be ported to the :type:`arf_t` type
|
|
|
|
by making use of :func:`arf_get_fmpz_2exp` and :func:`arf_set_fmpz_2exp`.
|
|
|
|
|
|
|
|
* Some :type:`arf_t` functions return an :type:`int`
|
|
|
|
indicating whether a result is inexact, whereas the corresponding
|
2015-11-06 11:45:33 +00:00
|
|
|
:type:`fmpr_t` functions return an :type:`slong` encoding the relative
|
2014-05-27 20:14:09 +02:00
|
|
|
exponent of the error.
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Types, macros and constants
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
.. type:: arf_struct
|
|
|
|
|
|
|
|
.. type:: arf_t
|
|
|
|
|
2015-01-28 18:20:07 +01:00
|
|
|
An :type:`arf_struct` contains four words: an :type:`fmpz` exponent (*exp*),
|
|
|
|
a *size* field tracking the number of limbs used (one bit of this
|
|
|
|
field is also used for the sign of the number), and two more words.
|
|
|
|
The last two words hold the value directly if there are at most two limbs,
|
|
|
|
and otherwise contain one *alloc* field (tracking the total number of
|
|
|
|
allocated limbs, not all of which might be used) and a pointer to
|
|
|
|
the actual limbs.
|
|
|
|
Thus, up to 128 bits on a 64-bit machine and 64 bits on a 32-bit machine,
|
|
|
|
no space outside of the :type:`arf_struct` is used.
|
|
|
|
|
2014-05-08 19:35:52 +02:00
|
|
|
An :type:`arf_t` is defined as an array of length one of type
|
|
|
|
:type:`arf_struct`, permitting an :type:`arf_t` to be passed by reference.
|
|
|
|
|
|
|
|
.. type:: arf_rnd_t
|
|
|
|
|
|
|
|
Specifies the rounding mode for the result of an approximate operation.
|
|
|
|
|
|
|
|
.. macro:: ARF_RND_DOWN
|
|
|
|
|
|
|
|
Specifies that the result of an operation should be rounded to the
|
|
|
|
nearest representable number in the direction towards zero.
|
|
|
|
|
|
|
|
.. macro:: ARF_RND_UP
|
|
|
|
|
|
|
|
Specifies that the result of an operation should be rounded to the
|
|
|
|
nearest representable number in the direction away from zero.
|
|
|
|
|
|
|
|
.. macro:: ARF_RND_FLOOR
|
|
|
|
|
|
|
|
Specifies that the result of an operation should be rounded to the
|
|
|
|
nearest representable number in the direction towards minus infinity.
|
|
|
|
|
|
|
|
.. macro:: ARF_RND_CEIL
|
|
|
|
|
|
|
|
Specifies that the result of an operation should be rounded to the
|
|
|
|
nearest representable number in the direction towards plus infinity.
|
|
|
|
|
|
|
|
.. macro:: ARF_RND_NEAR
|
|
|
|
|
|
|
|
Specifies that the result of an operation should be rounded to the
|
|
|
|
nearest representable number, rounding to an odd mantissa if there is a tie
|
2016-03-07 17:53:54 +01:00
|
|
|
between two values. **Warning**: this rounding mode is currently
|
2014-05-08 19:35:52 +02:00
|
|
|
not implemented (except for a few conversions functions where this
|
|
|
|
stated explicitly).
|
|
|
|
|
|
|
|
.. macro:: ARF_PREC_EXACT
|
|
|
|
|
|
|
|
If passed as the precision parameter to a function, indicates that no
|
2016-03-18 15:05:59 +01:00
|
|
|
rounding is to be performed. **Warning**: use of this value is unsafe in
|
|
|
|
general. It must only be
|
|
|
|
passed as input under the following two conditions:
|
|
|
|
|
|
|
|
* The operation in question can inherently be viewed as an exact operation
|
|
|
|
in `\mathbb{Z}[\tfrac{1}{2}]` for all possible inputs, provided that
|
|
|
|
the precision is large enough. Examples include addition,
|
|
|
|
multiplication, conversion from integer types to arbitrary-precision
|
|
|
|
floating-point types, and evaluation of some integer-valued functions.
|
|
|
|
|
|
|
|
* The exact result of the operation will certainly fit in memory.
|
|
|
|
Note that, for example, adding two numbers whose exponents are far
|
|
|
|
apart can easily produce an exact result that is far too large to
|
|
|
|
store in memory.
|
|
|
|
|
|
|
|
The typical use case is to work with small integer values, double
|
|
|
|
precision constants, and the like. It is also useful when writing
|
|
|
|
test code. If in doubt, simply try with some convenient high precision
|
|
|
|
instead of using this special value, and check that the result is exact.
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Memory management
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
.. function:: void arf_init(arf_t x)
|
|
|
|
|
|
|
|
Initializes the variable *x* for use. Its value is set to zero.
|
|
|
|
|
|
|
|
.. function:: void arf_clear(arf_t x)
|
|
|
|
|
|
|
|
Clears the variable *x*, freeing or recycling its allocated memory.
|
|
|
|
|
|
|
|
Special values
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
.. function:: void arf_zero(arf_t x)
|
|
|
|
|
|
|
|
.. function:: void arf_one(arf_t x)
|
|
|
|
|
|
|
|
.. function:: void arf_pos_inf(arf_t x)
|
|
|
|
|
|
|
|
.. function:: void arf_neg_inf(arf_t x)
|
|
|
|
|
|
|
|
.. function:: void arf_nan(arf_t x)
|
|
|
|
|
|
|
|
Sets *x* respectively to 0, 1, `+\infty`, `-\infty`, NaN.
|
|
|
|
|
|
|
|
.. function:: int arf_is_zero(const arf_t x)
|
|
|
|
|
|
|
|
.. function:: int arf_is_one(const arf_t x)
|
|
|
|
|
|
|
|
.. function:: int arf_is_pos_inf(const arf_t x)
|
|
|
|
|
|
|
|
.. function:: int arf_is_neg_inf(const arf_t x)
|
|
|
|
|
|
|
|
.. function:: int arf_is_nan(const arf_t x)
|
|
|
|
|
|
|
|
Returns nonzero iff *x* respectively equals 0, 1, `+\infty`, `-\infty`, NaN.
|
|
|
|
|
|
|
|
.. function:: int arf_is_inf(const arf_t x)
|
|
|
|
|
|
|
|
Returns nonzero iff *x* equals either `+\infty` or `-\infty`.
|
|
|
|
|
|
|
|
.. function:: int arf_is_normal(const arf_t x)
|
|
|
|
|
|
|
|
Returns nonzero iff *x* is a finite, nonzero floating-point value, i.e.
|
|
|
|
not one of the special values 0, `+\infty`, `-\infty`, NaN.
|
|
|
|
|
|
|
|
.. function:: int arf_is_special(const arf_t x)
|
|
|
|
|
|
|
|
Returns nonzero iff *x* is one of the special values
|
|
|
|
0, `+\infty`, `-\infty`, NaN, i.e. not a finite, nonzero
|
|
|
|
floating-point value.
|
|
|
|
|
|
|
|
.. function:: int arf_is_finite(arf_t x)
|
|
|
|
|
|
|
|
Returns nonzero iff *x* is a finite floating-point value,
|
|
|
|
i.e. not one of the values `+\infty`, `-\infty`, NaN.
|
|
|
|
(Note that this is not equivalent to the negation of
|
|
|
|
:func:`arf_is_inf`.)
|
|
|
|
|
|
|
|
|
|
|
|
Assignment, rounding and conversions
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
.. function:: void arf_set(arf_t y, const arf_t x)
|
|
|
|
|
|
|
|
.. function:: void arf_set_mpz(arf_t y, const mpz_t x)
|
|
|
|
|
|
|
|
.. function:: void arf_set_fmpz(arf_t y, const fmpz_t x)
|
|
|
|
|
|
|
|
.. function:: void arf_set_ui(arf_t y, ulong x)
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: void arf_set_si(arf_t y, slong x)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
.. function:: void arf_set_mpfr(arf_t y, const mpfr_t x)
|
|
|
|
|
|
|
|
.. function:: void arf_set_fmpr(arf_t y, const fmpr_t x)
|
|
|
|
|
2014-06-20 10:21:21 +02:00
|
|
|
.. function:: void arf_set_d(arf_t y, double x)
|
|
|
|
|
2014-05-08 19:35:52 +02:00
|
|
|
Sets *y* exactly to *x*.
|
|
|
|
|
|
|
|
.. function:: void arf_swap(arf_t y, arf_t x)
|
|
|
|
|
|
|
|
Swaps *y* and *x* efficiently.
|
|
|
|
|
|
|
|
.. function:: void arf_init_set_ui(arf_t y, ulong x)
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: void arf_init_set_si(arf_t y, slong x)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Initialises *y* and sets it to *x* in a single operation.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_set_round(arf_t y, const arf_t x, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_set_round_si(arf_t x, slong v, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_set_round_ui(arf_t x, ulong v, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_set_round_mpz(arf_t y, const mpz_t x, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_set_round_fmpz(arf_t y, const fmpz_t x, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Sets *y* to *x*, rounded to *prec* bits in the direction
|
|
|
|
specified by *rnd*.
|
|
|
|
|
2016-03-07 17:53:54 +01:00
|
|
|
Warning: :func:`arf_set_round` supports rounding to nearest
|
|
|
|
with *ARF_RND_NEAR*, but the other methods currently do not.
|
|
|
|
Rounding to nearest is currently much slower than the other rounding modes.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: void arf_set_si_2exp_si(arf_t y, slong m, slong e)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: void arf_set_ui_2exp_si(arf_t y, ulong m, slong e)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
.. function:: void arf_set_fmpz_2exp(arf_t y, const fmpz_t m, const fmpz_t e)
|
|
|
|
|
|
|
|
Sets *y* to `m \times 2^e`.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_set_round_fmpz_2exp(arf_t y, const fmpz_t x, const fmpz_t e, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Sets *y* to `x \times 2^e`, rounded to *prec* bits in the direction
|
|
|
|
specified by *rnd*.
|
|
|
|
|
|
|
|
.. function:: void arf_get_fmpz_2exp(fmpz_t m, fmpz_t e, const arf_t x)
|
|
|
|
|
|
|
|
Sets *m* and *e* to the unique integers such that
|
|
|
|
`x = m \times 2^e` and *m* is odd,
|
|
|
|
provided that *x* is a nonzero finite fraction.
|
|
|
|
If *x* is zero, both *m* and *e* are set to zero. If *x* is
|
|
|
|
infinite or NaN, the result is undefined.
|
|
|
|
|
2014-06-20 10:21:21 +02:00
|
|
|
.. function:: double arf_get_d(const arf_t x, arf_rnd_t rnd)
|
|
|
|
|
|
|
|
Returns *x* rounded to a double in the direction specified by *rnd*.
|
2015-10-02 11:29:43 +02:00
|
|
|
This method supports rounding to nearest with *ARF_RND_NEAR*.
|
|
|
|
It also rounds correctly when overflowing or underflowing
|
|
|
|
the double exponent range (this was not the case in an earlier version).
|
2014-06-20 10:21:21 +02:00
|
|
|
|
2014-05-08 19:35:52 +02:00
|
|
|
.. function:: void arf_get_fmpr(fmpr_t y, const arf_t x)
|
|
|
|
|
|
|
|
Sets *y* exactly to *x*.
|
|
|
|
|
|
|
|
.. function:: int arf_get_mpfr(mpfr_t y, const arf_t x, mpfr_rnd_t rnd)
|
|
|
|
|
|
|
|
Sets the MPFR variable *y* to the value of *x*. If the precision of *x*
|
|
|
|
is too small to allow *y* to be represented exactly, it is rounded in
|
|
|
|
the specified MPFR rounding mode. The return value (-1, 0 or 1)
|
|
|
|
indicates the direction of rounding, following the convention
|
|
|
|
of the MPFR library.
|
|
|
|
|
2016-02-26 16:57:19 +01:00
|
|
|
.. function:: int arf_get_fmpz(fmpz_t z, const arf_t x, arf_rnd_t rnd)
|
2014-06-20 10:21:21 +02:00
|
|
|
|
|
|
|
Sets *z* to *x* rounded to the nearest integer in the direction
|
|
|
|
specified by *rnd*. If rnd is *ARF_RND_NEAR*, rounds to the nearest
|
2016-02-26 16:57:19 +01:00
|
|
|
even integer in case of a tie. Returns inexact (beware: accordingly
|
|
|
|
returns whether *x* is *not* an integer).
|
2016-02-25 16:55:21 +01:00
|
|
|
|
|
|
|
This method aborts if *x* is infinite or NaN, or if the exponent of *x*
|
|
|
|
is so large that allocating memory for the result fails.
|
|
|
|
|
|
|
|
Warning: this method will allocate a huge amount of memory to store
|
|
|
|
the result if the exponent of *x* is huge. Memory allocation could
|
|
|
|
succeed even if the required space is far larger than the physical
|
|
|
|
memory available on the machine, resulting in swapping. It is recommended
|
|
|
|
to check that *x* is within a reasonable range before calling this method.
|
2014-06-20 10:21:21 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: slong arf_get_si(const arf_t x, arf_rnd_t rnd)
|
2014-06-20 10:21:21 +02:00
|
|
|
|
|
|
|
Returns *x* rounded to the nearest integer in the direction specified by
|
|
|
|
*rnd*. If *rnd* is *ARF_RND_NEAR*, rounds to the nearest even integer
|
|
|
|
in case of a tie. Aborts if *x* is infinite, NaN, or the value is
|
2015-11-06 11:45:33 +00:00
|
|
|
too large to fit in a slong.
|
2014-06-20 10:21:21 +02:00
|
|
|
|
|
|
|
.. function:: int arf_get_fmpz_fixed_fmpz(fmpz_t y, const arf_t x, const fmpz_t e)
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_get_fmpz_fixed_si(fmpz_t y, const arf_t x, slong e)
|
2014-06-20 10:21:21 +02:00
|
|
|
|
|
|
|
Converts *x* to a mantissa with predetermined exponent, i.e. computes
|
|
|
|
an integer *y* such that `y \times 2^e \approx x`, truncating if necessary.
|
|
|
|
Returns 0 if exact and 1 if truncation occurred.
|
|
|
|
|
2016-02-26 16:57:19 +01:00
|
|
|
The warnings for :func:`arf_get_fmpz` apply.
|
|
|
|
|
2014-10-30 15:54:50 +01:00
|
|
|
.. function:: void arf_floor(arf_t y, const arf_t x)
|
|
|
|
|
|
|
|
.. function:: void arf_ceil(arf_t y, const arf_t x)
|
|
|
|
|
|
|
|
Sets *y* to `\lfloor x \rfloor` and `\lceil x \rceil` respectively.
|
|
|
|
The result is always represented exactly, requiring no more bits to
|
|
|
|
store than the input. To round the result to a floating-point number
|
|
|
|
with a lower precision, call :func:`arf_set_round` afterwards.
|
|
|
|
|
2014-05-08 19:35:52 +02:00
|
|
|
Comparisons and bounds
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
.. function:: int arf_equal(const arf_t x, const arf_t y)
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_equal_si(const arf_t x, slong y)
|
2015-01-21 16:16:53 +01:00
|
|
|
|
2014-05-08 19:35:52 +02:00
|
|
|
Returns nonzero iff *x* and *y* are exactly equal. This function does
|
|
|
|
not treat NaN specially, i.e. NaN compares as equal to itself.
|
|
|
|
|
|
|
|
.. function:: int arf_cmp(const arf_t x, const arf_t y)
|
|
|
|
|
|
|
|
Returns negative, zero, or positive, depending on whether *x* is
|
|
|
|
respectively smaller, equal, or greater compared to *y*.
|
|
|
|
Comparison with NaN is undefined.
|
|
|
|
|
|
|
|
.. function:: int arf_cmpabs(const arf_t x, const arf_t y)
|
|
|
|
|
2014-05-09 16:50:01 +02:00
|
|
|
.. function:: int arf_cmpabs_ui(const arf_t x, ulong y)
|
|
|
|
|
|
|
|
.. function:: int arf_cmpabs_mag(const arf_t x, const mag_t y)
|
|
|
|
|
2014-05-08 19:35:52 +02:00
|
|
|
Compares the absolute values of *x* and *y*.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_cmp_2exp_si(const arf_t x, slong e)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_cmpabs_2exp_si(const arf_t x, slong e)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Compares *x* (respectively its absolute value) with `2^e`.
|
|
|
|
|
|
|
|
.. function:: int arf_sgn(const arf_t x)
|
|
|
|
|
|
|
|
Returns `-1`, `0` or `+1` according to the sign of *x*. The sign
|
|
|
|
of NaN is undefined.
|
|
|
|
|
|
|
|
.. function:: void arf_min(arf_t z, const arf_t a, const arf_t b)
|
|
|
|
|
|
|
|
.. function:: void arf_max(arf_t z, const arf_t a, const arf_t b)
|
|
|
|
|
|
|
|
Sets *z* respectively to the minimum and the maximum of *a* and *b*.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: slong arf_bits(const arf_t x)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Returns the number of bits needed to represent the absolute value
|
|
|
|
of the mantissa of *x*, i.e. the minimum precision sufficient to represent
|
|
|
|
*x* exactly. Returns 0 if *x* is a special value.
|
|
|
|
|
|
|
|
.. function:: int arf_is_int(const arf_t x)
|
|
|
|
|
|
|
|
Returns nonzero iff *x* is integer-valued.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_is_int_2exp_si(const arf_t x, slong e)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Returns nonzero iff *x* equals `n 2^e` for some integer *n*.
|
|
|
|
|
|
|
|
.. function:: void arf_abs_bound_lt_2exp_fmpz(fmpz_t b, const arf_t x)
|
|
|
|
|
|
|
|
Sets *b* to the smallest integer such that `|x| < 2^b`.
|
|
|
|
If *x* is zero, infinity or NaN, the result is undefined.
|
|
|
|
|
|
|
|
.. function:: void arf_abs_bound_le_2exp_fmpz(fmpz_t b, const arf_t x)
|
|
|
|
|
|
|
|
Sets *b* to the smallest integer such that `|x| \le 2^b`.
|
|
|
|
If *x* is zero, infinity or NaN, the result is undefined.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: slong arf_abs_bound_lt_2exp_si(const arf_t x)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Returns the smallest integer *b* such that `|x| < 2^b`, clamping
|
|
|
|
the result to lie between -*ARF_PREC_EXACT* and *ARF_PREC_EXACT*
|
|
|
|
inclusive. If *x* is zero, -*ARF_PREC_EXACT* is returned,
|
|
|
|
and if *x* is infinity or NaN, *ARF_PREC_EXACT* is returned.
|
|
|
|
|
2014-05-19 14:29:26 +02:00
|
|
|
Magnitude functions
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
2014-05-08 19:35:52 +02:00
|
|
|
.. function:: void arf_get_mag(mag_t y, const arf_t x)
|
|
|
|
|
2014-05-19 14:29:26 +02:00
|
|
|
Sets *y* to an upper bound for the absolute value of *x*.
|
|
|
|
|
2014-05-08 19:35:52 +02:00
|
|
|
.. function:: void arf_get_mag_lower(mag_t y, const arf_t x)
|
|
|
|
|
2014-05-19 14:29:26 +02:00
|
|
|
Sets *y* to a lower bound for the absolute value of *x*.
|
|
|
|
|
2014-05-08 19:35:52 +02:00
|
|
|
.. function:: void arf_set_mag(arf_t y, const mag_t x)
|
|
|
|
|
2014-05-19 14:29:26 +02:00
|
|
|
Sets *y* to *x*.
|
|
|
|
|
2014-05-08 19:35:52 +02:00
|
|
|
.. function:: void mag_init_set_arf(mag_t y, const arf_t x)
|
|
|
|
|
2014-05-19 14:29:26 +02:00
|
|
|
Initializes *y* and sets it to an upper bound for *x*.
|
|
|
|
|
2014-05-08 19:35:52 +02:00
|
|
|
.. function:: void mag_fast_init_set_arf(mag_t y, const arf_t x)
|
|
|
|
|
2014-05-19 14:29:26 +02:00
|
|
|
Initializes *y* and sets it to an upper bound for *x*.
|
|
|
|
Assumes that the exponent of *y* is small.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: void arf_mag_set_ulp(mag_t z, const arf_t y, slong prec)
|
2014-05-19 14:29:26 +02:00
|
|
|
|
|
|
|
Sets *z* to the magnitude of the unit in the last place (ulp) of *y*
|
|
|
|
at precision *prec*.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: void arf_mag_add_ulp(mag_t z, const mag_t x, const arf_t y, slong prec)
|
2014-05-19 14:29:26 +02:00
|
|
|
|
|
|
|
Sets *z* to an upper bound for the sum of *x* and the
|
|
|
|
magnitude of the unit in the last place (ulp) of *y*
|
|
|
|
at precision *prec*.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: void arf_mag_fast_add_ulp(mag_t z, const mag_t x, const arf_t y, slong prec)
|
2014-05-19 14:29:26 +02:00
|
|
|
|
|
|
|
Sets *z* to an upper bound for the sum of *x* and the
|
|
|
|
magnitude of the unit in the last place (ulp) of *y*
|
|
|
|
at precision *prec*. Assumes that all exponents are small.
|
|
|
|
|
2014-07-30 16:58:38 +02:00
|
|
|
Shallow assignment
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
.. function:: void arf_init_set_shallow(arf_t z, const arf_t x)
|
|
|
|
|
|
|
|
.. function:: void arf_init_set_mag_shallow(arf_t z, const mag_t x)
|
|
|
|
|
|
|
|
Initializes *z* to a shallow copy of *x*. A shallow copy just involves
|
|
|
|
copying struct data (no heap allocation is performed).
|
|
|
|
|
|
|
|
The target variable *z* may not be cleared or modified in any way (it can
|
|
|
|
only be used as constant input to functions), and may not be used after
|
|
|
|
*x* has been cleared. Moreover, after *x* has been assigned shallowly
|
2015-11-06 11:45:33 +00:00
|
|
|
to *z*, no modification of *x* is permitted as slong as *z* is in use.
|
2014-07-30 16:58:38 +02:00
|
|
|
|
|
|
|
.. function:: void arf_init_neg_shallow(arf_t z, const arf_t x)
|
|
|
|
|
|
|
|
.. function:: void arf_init_neg_mag_shallow(arf_t z, const mag_t x)
|
|
|
|
|
|
|
|
Initializes *z* shallowly to the negation of *x*.
|
|
|
|
|
2014-05-08 19:35:52 +02:00
|
|
|
Random number generation
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: void arf_randtest(arf_t x, flint_rand_t state, slong bits, slong mag_bits)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Generates a finite random number whose mantissa has precision at most
|
|
|
|
*bits* and whose exponent has at most *mag_bits* bits. The
|
|
|
|
values are distributed non-uniformly: special bit patterns are generated
|
|
|
|
with high probability in order to allow the test code to exercise corner
|
|
|
|
cases.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: void arf_randtest_not_zero(arf_t x, flint_rand_t state, slong bits, slong mag_bits)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Identical to :func:`arf_randtest`, except that zero is never produced
|
|
|
|
as an output.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: void arf_randtest_special(arf_t x, flint_rand_t state, slong bits, slong mag_bits)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Indentical to :func:`arf_randtest`, except that the output occasionally
|
|
|
|
is set to an infinity or NaN.
|
|
|
|
|
|
|
|
Input and output
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
.. function:: void arf_debug(const arf_t x)
|
|
|
|
|
|
|
|
Prints information about the internal representation of *x*.
|
|
|
|
|
|
|
|
.. function:: void arf_print(const arf_t x)
|
|
|
|
|
|
|
|
Prints *x* as an integer mantissa and exponent.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: void arf_printd(const arf_t y, slong d)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Prints *x* as a decimal floating-point number, rounding to *d* digits.
|
|
|
|
This function is currently implemented using MPFR,
|
|
|
|
and does not support large exponents.
|
|
|
|
|
2015-12-31 18:26:05 -05:00
|
|
|
.. function:: void arf_fprint(FILE * file, const arf_t x)
|
|
|
|
|
|
|
|
Prints *x* as an integer mantissa and exponent to the stream *file*.
|
|
|
|
|
|
|
|
.. function:: void arf_fprintd(FILE * file, const arf_t y, slong d)
|
|
|
|
|
|
|
|
Prints *x* as a decimal floating-point number to the stream *file*,
|
|
|
|
rounding to *d* digits. This function is currently implemented using MPFR,
|
|
|
|
and does not support large exponents.
|
|
|
|
|
2014-06-20 10:21:21 +02:00
|
|
|
Addition and multiplication
|
2014-05-08 19:35:52 +02:00
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
.. function:: void arf_abs(arf_t y, const arf_t x)
|
|
|
|
|
|
|
|
Sets *y* to the absolute value of *x*.
|
|
|
|
|
|
|
|
.. function:: void arf_neg(arf_t y, const arf_t x)
|
|
|
|
|
|
|
|
Sets `y = -x` exactly.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_neg_round(arf_t y, const arf_t x, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Sets `y = -x`, rounded to *prec* bits in the direction specified by *rnd*,
|
|
|
|
returning nonzero iff the operation is inexact.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: void arf_mul_2exp_si(arf_t y, const arf_t x, slong e)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
.. function:: void arf_mul_2exp_fmpz(arf_t y, const arf_t x, const fmpz_t e)
|
|
|
|
|
|
|
|
Sets `y = x 2^e` exactly.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_mul(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_mul_ui(arf_t z, const arf_t x, ulong y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_mul_si(arf_t z, const arf_t x, slong y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_mul_mpz(arf_t z, const arf_t x, const mpz_t y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_mul_fmpz(arf_t z, const arf_t x, const fmpz_t y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Sets `z = x \times y`, rounded to *prec* bits in the direction specified by *rnd*,
|
|
|
|
returning nonzero iff the operation is inexact.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_add(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_add_si(arf_t z, const arf_t x, slong y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_add_ui(arf_t z, const arf_t x, ulong y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_add_fmpz(arf_t z, const arf_t x, const fmpz_t y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Sets `z = x + y`, rounded to *prec* bits in the direction specified by *rnd*,
|
|
|
|
returning nonzero iff the operation is inexact.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_add_fmpz_2exp(arf_t z, const arf_t x, const fmpz_t y, const fmpz_t e, slong prec, arf_rnd_t rnd)
|
2014-06-20 10:21:21 +02:00
|
|
|
|
|
|
|
Sets `z = x + y 2^e`, rounded to *prec* bits in the direction specified by *rnd*,
|
|
|
|
returning nonzero iff the operation is inexact.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_sub(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_sub_si(arf_t z, const arf_t x, slong y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_sub_ui(arf_t z, const arf_t x, ulong y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_sub_fmpz(arf_t z, const arf_t x, const fmpz_t y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Sets `z = x - y`, rounded to *prec* bits in the direction specified by *rnd*,
|
|
|
|
returning nonzero iff the operation is inexact.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_addmul(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_addmul_ui(arf_t z, const arf_t x, ulong y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_addmul_si(arf_t z, const arf_t x, slong y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_addmul_mpz(arf_t z, const arf_t x, const mpz_t y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_addmul_fmpz(arf_t z, const arf_t x, const fmpz_t y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Sets `z = z + x \times y`, rounded to *prec* bits in the direction specified by *rnd*,
|
|
|
|
returning nonzero iff the operation is inexact.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_submul(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_submul_ui(arf_t z, const arf_t x, ulong y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_submul_si(arf_t z, const arf_t x, slong y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_submul_mpz(arf_t z, const arf_t x, const mpz_t y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_submul_fmpz(arf_t z, const arf_t x, const fmpz_t y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Sets `z = z - x \times y`, rounded to *prec* bits in the direction specified by *rnd*,
|
|
|
|
returning nonzero iff the operation is inexact.
|
|
|
|
|
2014-06-20 10:21:21 +02:00
|
|
|
Summation
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_sum(arf_t s, arf_srcptr terms, slong len, slong prec, arf_rnd_t rnd)
|
2014-06-20 10:21:21 +02:00
|
|
|
|
|
|
|
Sets *s* to the sum of the array *terms* of length *len*, rounded to
|
|
|
|
*prec* bits in the direction specified by *rnd*. The sum is computed as if
|
|
|
|
done without any intermediate rounding error, with only a single rounding
|
|
|
|
applied to the final result. Unlike repeated calls to :func:`arf_add` with
|
|
|
|
infinite precision, this function does not overflow if the magnitudes of
|
|
|
|
the terms are far apart. Warning: this function is implemented naively,
|
|
|
|
and the running time is quadratic with respect to *len* in the worst case.
|
|
|
|
|
|
|
|
Division
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_div(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_div_ui(arf_t z, const arf_t x, ulong y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_ui_div(arf_t z, ulong x, const arf_t y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_div_si(arf_t z, const arf_t x, slong y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_si_div(arf_t z, slong x, const arf_t y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_div_fmpz(arf_t z, const arf_t x, const fmpz_t y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_fmpz_div(arf_t z, const fmpz_t x, const arf_t y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_fmpz_div_fmpz(arf_t z, const fmpz_t x, const fmpz_t y, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Sets `z = x / y`, rounded to *prec* bits in the direction specified by *rnd*,
|
|
|
|
returning nonzero iff the operation is inexact. The result is NaN if *y* is zero.
|
|
|
|
|
2014-06-20 10:21:21 +02:00
|
|
|
Square roots
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_sqrt(arf_t z, const arf_t x, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_sqrt_ui(arf_t z, ulong x, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_sqrt_fmpz(arf_t z, const fmpz_t x, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Sets `z = \sqrt{x}`, rounded to *prec* bits in the direction specified by *rnd*,
|
|
|
|
returning nonzero iff the operation is inexact. The result is NaN if *x* is negative.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_rsqrt(arf_t z, const arf_t x, slong prec, arf_rnd_t rnd)
|
2014-05-08 19:35:52 +02:00
|
|
|
|
|
|
|
Sets `z = 1/\sqrt{x}`, rounded to *prec* bits in the direction specified by *rnd*,
|
|
|
|
returning nonzero iff the operation is inexact. The result is NaN if *x* is
|
|
|
|
negative, and `+\infty` if *x* is zero.
|
2014-05-08 14:48:36 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_root(arf_t z, const arf_t x, ulong k, slong prec, arf_rnd_t rnd)
|
2015-06-17 18:37:53 +02:00
|
|
|
|
|
|
|
Sets `z = x^{1/k}`, rounded to *prec* bits in the direction specified by *rnd*,
|
|
|
|
returning nonzero iff the operation is inexact. The result is NaN if *x* is negative.
|
|
|
|
Warning: this function is a wrapper around the MPFR root function.
|
|
|
|
It gets slow and uses much memory for large *k*.
|
|
|
|
|
2014-06-20 10:21:21 +02:00
|
|
|
Complex arithmetic
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_complex_mul(arf_t e, arf_t f, const arf_t a, const arf_t b, const arf_t c, const arf_t d, slong prec, arf_rnd_t rnd)
|
2014-06-20 10:21:21 +02:00
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_complex_mul_fallback(arf_t e, arf_t f, const arf_t a, const arf_t b, const arf_t c, const arf_t d, slong prec, arf_rnd_t rnd)
|
2014-06-20 10:21:21 +02:00
|
|
|
|
|
|
|
Computes the complex product `e + fi = (a + bi)(c + di)`, rounding both
|
|
|
|
`e` and `f` correctly to *prec* bits in the direction specified by *rnd*.
|
|
|
|
The first bit in the return code indicates inexactness of `e`, and the
|
|
|
|
second bit indicates inexactness of `f`.
|
|
|
|
|
|
|
|
If any of the components *a*, *b*, *c*, *d* is zero, two real
|
|
|
|
multiplications and no additions are done. This convention is used even
|
|
|
|
if any other part contains an infinity or NaN, and the behavior
|
|
|
|
with infinite/NaN input is defined accordingly.
|
|
|
|
|
|
|
|
The *fallback* version is implemented naively, for testing purposes.
|
|
|
|
No squaring optimization is implemented.
|
|
|
|
|
2015-11-06 11:45:33 +00:00
|
|
|
.. function:: int arf_complex_sqr(arf_t e, arf_t f, const arf_t a, const arf_t b, slong prec, arf_rnd_t rnd)
|
2014-06-20 10:21:21 +02:00
|
|
|
|
|
|
|
Computes the complex square `e + fi = (a + bi)^2`. This function has
|
|
|
|
identical semantics to :func:`arf_complex_mul` (with `c = a, b = d`),
|
|
|
|
but is faster.
|
|
|
|
|
2016-02-28 02:07:04 +01:00
|
|
|
Low-level methods
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
.. function:: int _arf_get_integer_mpn(mp_ptr y, mp_srcptr xp, mp_size_t xn, slong exp)
|
|
|
|
|
|
|
|
Given a floating-point number *x* represented by *xn* limbs at *xp*
|
|
|
|
and an exponent *exp*, writes the integer part of *x* to
|
2016-02-28 02:29:20 +01:00
|
|
|
*y*, returning whether the result is inexact.
|
2016-02-28 02:07:04 +01:00
|
|
|
The correct number of limbs is written (no limbs are written
|
|
|
|
if the integer part of *x* is zero).
|
|
|
|
Assumes that ``xp[0]`` is nonzero and that the
|
|
|
|
top bit of ``xp[xn-1]`` is set.
|
|
|
|
|
2016-02-28 02:29:20 +01:00
|
|
|
.. function:: int _arf_set_mpn_fixed(arf_t z, mp_srcptr xp, mp_size_t xn, mp_size_t fixn, int negative, slong prec, arf_rnd_t rnd)
|
|
|
|
|
|
|
|
Sets *z* to the fixed-point number having *xn* total limbs and *fixn*
|
|
|
|
fractional limbs, negated if *negative* is set, rounding *z* to *prec*
|
|
|
|
bits in the direction *rnd* and returning whether the result is inexact.
|
|
|
|
Both *xn* and *fixn* must be nonnegative and not so large
|
|
|
|
that the bit shift would overflow an *slong*, but otherwise no
|
|
|
|
assumptions are made about the input.
|
|
|
|
|