Skip to content

Conversation

@Munksgaard
Copy link
Contributor

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

@whatyouhide
Copy link
Owner

This doesn't affect "normal" use cases where the range is much smaller, right? (Given the issue only appears with large numbers)

@coveralls
Copy link

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%
Totals Coverage Status
Change from base Build 1f220e88b6df08fbe5a3f83c8e1c35d887171bf5: -0.5%
Covered Lines: 381
Relevant Lines: 407

💛 - Coveralls

@Munksgaard
Copy link
Contributor Author

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

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 whatyouhide#203
@Munksgaard
Copy link
Contributor Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

float() will return 0.0 as a valid value if min is a very small number and max is approaching 0 from the neg. side

3 participants