Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-8178] Fix BinaryFloatingPoint.random(in:) open range returning upperBound #17794

Merged
merged 2 commits into from Jul 6, 2018

Conversation

Azoy
Copy link
Member

@Azoy Azoy commented Jul 6, 2018

The problem seemed to come from the final addition + range.lowerBound.

@Azoy
Copy link
Member Author

Azoy commented Jul 6, 2018

cc: @stephentyrone

@Azoy Azoy changed the title [SR-8178] Fix open range returning upperBound [SR-8178] Fix BinaryFloatingPoint.random(in:) open range returning upperBound Jul 6, 2018
if randFloat == range.upperBound {
return randFloat.nextDown
}
% end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This introduces a (very slight) bias, as it effectively makes the penultimate value 1.5 times more likely to occur than every other value in the binade. As a hacky quick fix to preserve the desired invariant, it's semi-acceptable, but let's see if we can get a better long-term fix done instead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll either make a patch myself or send you some notes on how to do this in a more principled way later today.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me. Would love to get some notes even if you patch it yourself if that's fine.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely. Thanks for adding the new tests, by the way; do you want to amend this PR to just the tests, and we'll land those as an expected-fail in the meantime?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, why don't you amend this patch as follows: instead of mapping upperBound to the next smaller value, simply re-draw if upperBound is generated. This is slightly inefficient, but completely eliminates the bias.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we re-draw with the same max rng, wouldn't we be forever re-drawing since upperBound would always be occurring?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that is a concern, though it won't happen with non-pathological RNGs =)

Maybe for the test use an RNG that instead generates [.min, .max, basic LCG sequence ...].

Copy link
Member

@stephentyrone stephentyrone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixes. In most circumstances we would usually favor repeat-while over explicit recursion like this, but in this case the probabilities decay so fast that it's really a non-issue.

@stephentyrone
Copy link
Member

@swift-ci please smoke test.

@stephentyrone stephentyrone merged commit 79cb33f into apple:master Jul 6, 2018
@Azoy Azoy deleted the sr-8178 branch July 10, 2018 16:31
stephentyrone pushed a commit to stephentyrone/swift that referenced this pull request Jul 10, 2018
stephentyrone added a commit that referenced this pull request Jul 10, 2018
* [SR-8178] Fix BinaryFloatingPoint.random(in:) open range returning upperBound (#17794)

* Require .upperBound - .lowerBound be finite for FloatingPoint random (#17833)

This is a slightly conservative precondition; when we re-work the FloatingPoint random computation in a more principled fashion, we can relax this to only requiring that .upperBound and .lowerBound are both finite. However, the current computation will break down unless this conservative condition is used, and this is future proof--we will only relax it going forward.
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.

None yet

2 participants