Last update: Jan 3, 2022

Library for arithmetics with double-double precision

Masahide Kashiwagi

This library (dd.hpp) has:

- (approximate) the four arithmetic operations
- (approximate) the sqrt function
- equality and inequality
- abs, floor, and frexp
- mathematical functions, e.g., exp, log, sin, cos, tan, sinh, cosh, tanh, asin, acos, atan, asinh, acosh, atanh, expm1, log1p, and pow
- the interconversion between dd-type numbers and decimal-number characters

- the four arithmetic operations with changing a rounding mode
- the sqrt operation with changing a rounding mode
- the interconversion between dd's and characters with specifying a rounding mode

(requiring conv-dd.hpp, fpu53.hpp, convert.hpp, and constants.hpp)

rdd.hpp

(requiring hwround.hpp, rdd-hwround.hpp, and rdd-nohwround.hpp)

- the traditional FPU;
- SSE2 in recent CPUs.

The computational precision in FPU is 80bit (total) and 64bit (significand), which is different from the IEEE754 standard of 64bit (total) and 53bit (significand). This causes deviance in dd-precision arithmetics.

On the other hand, SSE2 conforms the IEEE754 standard and Intel's CPUs in the 64bit mode employs not FPU but SSE2. Therefore, in the 64bit mode, such deviance does not occur. Even in the use of 32bit CPUs, "-msse2 -mfpmath=sse" provides a safe computation.

Fortunately, in the FPU Control Register, there is the flag that specifies a computational precision. If one can change this flag from 64bit to 53bit, the deviance due to FPU is prevented. Although this can be done with including fpu53.h in this library, some compiler may not support this change.

(Modified in version 0.4.54.) In order for dd operations to work properly, it must be fully compilant with IEEE754. For example, the 32bit environment of Intel CPU may not comply with IEEE754, so kv library cannot be compiled in such an environment. Actually, after #include <cfloat>, the macro FLT_EVAL_METHOD is checked, and if it is not 0, it is an error and cannot be compiled. If you really want to use kv in 32bit Intel CPU environment, you can use -msse2 -mfpmath=sse compile option to use SSE2, which will set the above macro to 0 and allow you to compile. We decided not to support compilers that do not define this macro, or CPUs that do not have SSE2, because they are too old.

double x, y; int i; y = frexp(x, &i);for input x, we can get y, i such that 0.5 ≤ |y| < 1、x=y×2

kv::dd x, y; int i; y = frexp(x, &i);

However, considering the input dd number such that the magnitude of high and low is
much different, for example, x=1+2^{-1074},
the output of frexp should be y=0.5+2^{-1075}, i=1, but
it is impossible because 2^{-1075} is not representable by
double precision format.
Namely, frexp for double is error-free, but, be careful to the fact that
frexp for dd may include error in very special case.
Note that the exponent i is always reliable.

stringtodd, ddtostring contained in conv-dd.hpp performs mutual conversion between dd type and decimal character string. Since conv-dd.hpp can be used alone, if you are troubled with dd input/output, please use it.

We implemented infinite similar to IEEE 754 Std. The internal representation is (±∞, 0).