-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
bugfixes in Libc.rand for Windows #32895
Conversation
# on non-Windows systems (in practice, it's 2^31-1) | ||
rand(::Type{UInt32}) = ((rand() % UInt32) << 16) ⊻ (rand() % UInt32) | ||
end | ||
rand(::Type{Float64}) = rand(UInt32) * 2.0^-32 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use ldexp
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@code_native g(UInt32(3))
reports an enormous amount of code for g(x) = ldexp(Float64(x), -32)
for some reason…
(ldexp(x, n)
only currently supports floating-point x
.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think ldexp
is probably slower here here because it doesn't seem to constant-propagate the exponent?
Note that |
Indeed a call to |
Test failure seems unrelated? |
This is so strange! Windows (libC there) still is struck in 16-bit world (for compatibility with old code, why not other platforms?)? So Libc.rand(Int) is non-portable, "affecting" Julia too, with the different RAND_MAX depending on platforms?
I'm not sure who actually uses it outside of the standard library, but shouldn't Libc.rand just be deprecated, at least less precise Libc.rand(Float64)? Other problems there, e.g. "twice" docs is outdated for Windows:
|
Okay to merge? |
Fixes a bug noted by @mschauer in #32894 (comment), which seems to originate in #24874 by @rfourquet, where the code used a
/ 2^32
expression that overflows on 32-bit machines. This PR uses* 2.0^-32
instead, which constant folds and is exact inFloat64
.Also fixes another problem in the same code on Windows — the code assumed that
RAND_MAX
is at least2^16-1
, which seems to be true on supported Unix systems (GNU and BSD), but on Windows it is2^15-1
so we need a thirdrand
call to get 32 bits of randomness (or "randomness").