.. _issues: Potential issues =============================================================================== Interface changes ------------------------------------------------------------------------------- As this is an early version, note that any part of the interface is subject to change without warning! Most of the core interface should be stable at this point, but no guarantees are made. Correctness ------------------------------------------------------------------------------- Except where otherwise specified, Arb is designed to produce provably correct error bounds. The code has been written carefully, and the library is extensively tested. However, like any complex mathematical software, Arb is virtually certain to contains bugs, so the usual precautions are advised: * Perform sanity checks on the output (check known mathematical relations; recompute to another precision and compare) * Compare against other mathematical software * Read the source code to verify that it does what it is supposed to do All bug reports are highly welcome! Integer overflow ------------------------------------------------------------------------------- Machine-size integers are used for precisions, sizes of integers in bits, lengths of polynomials, and similar quantities that relate to sizes in memory. Very few checks are performed to verify that such quantities do not overflow. Precisions and lengths exceeding a small fraction of *LONG_MAX*, say `2^{24} \sim 10^7` on 32-bit systems, should be regarded as resulting in undefined behavior. On 64-bit systems this should generally not be an issue, since most calculations will exhaust the available memory (or the user's patience waiting for the computation to complete) long before running into integer overflows. However, the user needs to be wary of unintentionally passing input parameters of order *LONG_MAX* or negative parameters where positive parameters are expected, for example due to a runaway loop that repeatedly increases the precision. This caveat does not apply to exponents of floating-point numbers, which are represented as arbitrary-precision integers, nor to integers used as numerical scalars (e.g. :func:`fmprb_mul_si`). However, it still applies to conversions and operations where the result is requested exactly and sizes become an issue. For example, trying to convert the floating-point number `2^{2^{100}}` to an integer could result in anything from a silent wrong value to thrashing followed by a crash, and it is the user's responsibility not to attempt such a thing. Thread safety and caches ------------------------------------------------------------------------------- Arb should be fully threadsafe, provided that both MPFR and FLINT have been built in threadsafe mode. Please note that thread safety is not currently tested, and extra caution when developing multithreaded code is therefore recommended. Arb may cache some data (such as the value of `\pi` and Bernoulli numbers) to speed up various computations. In threadsafe mode, caches use thread-local storage (there is currently no way to save memory and avoid recomputation by having several threads share the same cache). Caches can be freed by calling the ``flint_cleanup()`` function. To avoid memory leaks, the user should call ``flint_cleanup()`` when exiting a thread. It is also recommended to call ``flint_cleanup()`` when exiting the main program (this should result in a clean output when running `Valgrind `_, and can help catching memory issues). Use of hardware floating-point arithmetic ------------------------------------------------------------------------------- Arb uses hardware floating-point arithmetic (the ``double`` type in C) in two different ways. Firstly, ``double`` arithmetic as well as transcendental ``libm`` functions (such as ``exp``, ``log``) are used to select parameters heuristically in various algorithms. Such heuristic use of approximate arithmetic does not affect correctness: when any error bounds depend on the parameters, the error bounds are evaluated separately using rigorous methods. At worst, flaws in the floating-point arithmetic on a particular machine could cause an algorithm to become inefficient due to inefficient parameters being selected. Secondly, ``double`` arithmetic is used internally for some rigorous error bound calculations. To guarantee correctness, we make the following assumptions. With the stated exceptions, these should hold on all commonly used platforms. * A ``double`` uses the standard IEEE 754 format (with a 53-bit significand, 11-bit exponent, encoding of infinities and NaNs, etc.) * We assume that the compiler does not perform "unsafe" floating-point optimizations, such as reordering of operations. Unsafe optimizations are disabled by default in most modern C compilers, including GCC and Clang. The exception appears to be the Intel C++ compiler, which does some unsafe optimizations by default. These must be disabled by the user. * We do not assume that floating-point operations are correctly rounded (a counterexample is the x87 FPU), or that rounding is done in any particular direction (the rounding mode may have been changed by the user). We assume that any floating-point operation is done with at most 1.1 ulp error. * We do not assume that underflow or overflow behaves in a particular way (we only use doubles that fit in the regular exponent range, or explicit infinities). * We do not use transcendental ``libm`` functions, since these can have errors of several ulps, and there is unfortunately no way to get guaranteed bounds. However, we do use functions such as ``ldexp`` and ``sqrt``, which we assume to be correctly implemented.