GAOL computes pow(I, n) by repeated rounded products (uipow()), and nth_root(I, n) with mathlib's upow() and a rounded exponent 1/n. The bounds enclose the exact values, but can be several floats away from the tightest ones.
tests/arithmetic.cpp compares them exactly on 5000 random doubles. Largest number of floats between GAOL's bounds and the tightest ones, over all the platforms of the continuous integration:
|
exponents from -30 to 30 |
any double |
pow([a], n) for n = 3, 4, 5, 6, 7 |
2, 3, 5, 6, 8 |
2, 3, 5, 6, 7 |
pow([a], -n) for n = 2, 3 |
2, 4 |
3, 4 (when a^n is a double) |
nth_root([a], n) for n = 3, 5, 6, 7 |
8, 4, 4, 4 |
234, 106, 117, 127 |
nth_root([a], n) for n = 2, 4, and sqrt([a]) |
1 |
1 |
pow([a], -n) is computed as 1/a^n. When a^n is beyond the largest double, the result is [0, 1/max]: pow([0x1.346d964e3694dp+536], -2) = [0, 0x0.4000000000001p-1022], while the exact value is near 2^-1072.
The tests allow about twice these distances. Two possible improvements:
- Roots could be corrected as the square root now is (3257c31): check each bound with exact products, and move it by a float when it is not a bound yet.
- Small integer powers could be computed with exact products (double-double).
GAOL computes
pow(I, n)by repeated rounded products (uipow()), andnth_root(I, n)with mathlib'supow()and a rounded exponent 1/n. The bounds enclose the exact values, but can be several floats away from the tightest ones.tests/arithmetic.cppcompares them exactly on 5000 random doubles. Largest number of floats between GAOL's bounds and the tightest ones, over all the platforms of the continuous integration:pow([a], n)for n = 3, 4, 5, 6, 7pow([a], -n)for n = 2, 3nth_root([a], n)for n = 3, 5, 6, 7nth_root([a], n)for n = 2, 4, andsqrt([a])pow([a], -n)is computed as1/a^n. Whena^nis beyond the largest double, the result is[0, 1/max]:pow([0x1.346d964e3694dp+536], -2) = [0, 0x0.4000000000001p-1022], while the exact value is near 2^-1072.The tests allow about twice these distances. Two possible improvements: