Apply filter to float_with_bounds
Computing floats when given bounds such as min -9.9e15 and max -1 will result in the computation -1.0 - -9.9e15 yielding 9900000000000000.0 instead of 9899999999999999.0, which makes the generator return 0. This is a classic floating point loss of significance error.
Fixes #203
This doesn't affect "normal" use cases where the range is much smaller, right? (Given the issue only appears with large numbers)
Pull Request Test Coverage Report for Build 31fb904be9ebaa45226865061bbc324135f32300-PR-219
Details
- 2 of 2 (100.0%) changed or added relevant lines in 1 file are covered.
- 2 unchanged lines in 1 file lost coverage.
- Overall coverage decreased (-0.5%) to 93.612%
| Files with Coverage Reduction | New Missed Lines | % |
|---|---|---|
| lib/stream_data.ex | 2 | 93.99% |
| <!-- | Total: | 2 |
| Totals | |
|---|---|
| Change from base Build 1f220e88b6df08fbe5a3f83c8e1c35d887171bf5: | -0.5% |
| Covered Lines: | 381 |
| Relevant Lines: | 407 |
💛 - Coveralls
This doesn't affect "normal" use cases where the range is much smaller, right? (Given the issue only appears with large numbers)
This happens because floats lose precision at $2^{53}$. Up until that number, all integers are exactly representable as IEEE doubles, but after $2^{53}$, only the even numbers are representable. You'll notice that $9.9e14 < 2^{53} < 9.9e15$, which means that 9.9e15 - 1.0 == 9.9e15 returns true in Elixir.
For smaller numbers, this can still be a problem, for instance from $2^{52}$ to $2^{53}$, only whole integers are representable, so 2.0**52 + 0.5 == 2.0**52 is true in Elixir (and all other languages that use IEEE doubles).
More information: https://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64
I've updated the PR to make it more likely that the special cases are hit in tests. Hopefully that should help fix the coveralls regression.