Skip to content

Commit

Permalink
Slightly improve accuracy of stod in to_floats (#10622)
Browse files Browse the repository at this point in the history
Reference #10599 

Provides a slight improvement in accuracy for the internal stod device function used by the `cudf::strings::to_floats()` API.

Reduces the number of floating-point operations by 1 and also applies the exponent by conditionally multiplying or dividing depending on it being positive or negative. This slightly improves accuracy of the result since multiplying decimal fractions in floating point can compound errors.

```
>>> s = cudf.Series(['1.0','2.0','0.1','0.2','0.3'])
>>> x = cudf.to_numeric(s)
>>> x[0]
1.0        previously 0.9999999999999999
>>> x[1]
2.0        previously 1.9999999999999998
>>> x[2]
0.1        previously 0.09999999999999999
>>> x[3]
0.2        previously 0.19999999999999998
>>> x[4]
0.3        same
```

The 1.0 floating-point value in bits was `3FEFFFFFFFFFFFFF` and now computes to `3FF0000000000000` which is 1.0.
The 0.1 floating-point value in bits was `3FB9999999999999` and now computes to `3FB999999999999A` which is now 0.10000000000000001 so the error is the same as 0.09999999999999999 but both are within expected epsilon.

Since the overall error is within `std::numerics<T>::epsilon()` error threshold, no tests had to be modified.

Authors:
  - David Wendt (https://github.com/davidwendt)

Approvers:
  - Vyas Ramasubramani (https://github.com/vyasr)
  - Karthikeyan (https://github.com/karthikeyann)

URL: #10622
  • Loading branch information
davidwendt authored Apr 11, 2022
1 parent c8ffece commit 012af64
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions cpp/src/strings/convert/convert_floats.cu
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,11 @@ __device__ inline double stod(string_view const& d_str)
else if (exp_ten < std::numeric_limits<double>::min_exponent10)
return double{0};

exp_ten += 1 - num_digits;
// exp10() is faster than pow(10.0,exp_ten)
double const base =
sign * static_cast<double>(digits) * exp10(static_cast<double>(1 - num_digits));
double const exponent = exp10(static_cast<double>(exp_ten));
return base * exponent;
double const exponent = exp10(static_cast<double>(std::abs(exp_ten)));
double const base = sign * static_cast<double>(digits);
return exp_ten < 0 ? base / exponent : base * exponent;
}

/**
Expand Down

0 comments on commit 012af64

Please sign in to comment.