Closed yotann closed 2 years ago
These bugs only affect the rounding modes toward_plus_infinity, toward_minus_infinity, and away_from_zero.
toward_plus_infinity
toward_minus_infinity
away_from_zero
In the paper, Algorithm A.1 step 7 currently says:
x = (fc - 1/2) * 2^e * 10^k = (2*fc - 1) * 2^{e-1} * 10^k for the normal interval case
x = (fc - 1/2) * 2^e * 10^k = (2*fc - 1) * 2^{e-1} * 10^k
x = (fc - 1/4) * 2^e * 10^k = (4*fc - 1) * 2^{e-2} * 10^k for the shorter interval case
x = (fc - 1/4) * 2^e * 10^k = (4*fc - 1) * 2^{e-2} * 10^k
These are incorrect for right-closed directed rounding, which uses w-; see the definition of w- in section 2.2. The correct values are:
x = (fc - 1) * 2^e * 10^k = (2*fc - 2) * 2^{e-1} * 10^k for the normal interval case
x = (fc - 1) * 2^e * 10^k = (2*fc - 2) * 2^{e-1} * 10^k
x = (fc - 1/2) * 2^e * 10^k = (2*fc - 1) * 2^{e-1} * 10^k for the shorter interval case
#include <iomanip> #include <iostream> #include <limits> #include "dragonbox/dragonbox.h" template<typename Float> static void away_from_zero(Float f) { auto v = jkj::dragonbox::to_decimal(f, jkj::dragonbox::policy::decimal_to_binary_rounding::away_from_zero); std::cout << std::scientific; std::cout << std::setprecision(std::numeric_limits<Float>::digits10 + 5); std::cout << f << ": " << v.significand << "E" << v.exponent << "\n"; } int main(int argc, char **argv) { away_from_zero(5e-324); away_from_zero(3.33e-321); away_from_zero(3.335e-321); away_from_zero(1.547425049106725e+26); away_from_zero(1.5474250491067252e+26); away_from_zero(35184369991680.0f); away_from_zero(35184372088832.0f); return 0; }
4.94065645841246544177e-324: 0E-307 3.33000245297000170775e-321: 333E-323 3.33494310942841417319e-321: 333E-323 1.54742504910672500003e+26: 1547425049106725E11 1.54742504910672517183e+26: 1547425049106725E11 3.51843699917e+13: 35184369E6 3.51843720888e+13: 35184372E6
4.94065645841246544177e-324: 4E-324 3.33000245297000170775e-321: 333E-323 3.33494310942841417319e-321: 3334E-324 1.54742504910672500003e+26: 1547425049106725E11 1.54742504910672517183e+26: 15474250491067251E10 3.51843699917e+13: 35184369E6 3.51843720888e+13: 3518437E7
Thanks a lot for catching this!
These bugs only affect the rounding modes
toward_plus_infinity
,toward_minus_infinity
, andaway_from_zero
.In the paper, Algorithm A.1 step 7 currently says:
x = (fc - 1/2) * 2^e * 10^k = (2*fc - 1) * 2^{e-1} * 10^k
for the normal interval casex = (fc - 1/4) * 2^e * 10^k = (4*fc - 1) * 2^{e-2} * 10^k
for the shorter interval caseThese are incorrect for right-closed directed rounding, which uses w-; see the definition of w- in section 2.2. The correct values are:
x = (fc - 1) * 2^e * 10^k = (2*fc - 2) * 2^{e-1} * 10^k
for the normal interval casex = (fc - 1/2) * 2^e * 10^k = (2*fc - 1) * 2^{e-1} * 10^k
for the shorter interval caseTest program
Incorrect output
Fixed output