-
Notifications
You must be signed in to change notification settings - Fork 30
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
Test on i386 #141
base: master
Are you sure you want to change the base?
Test on i386 #141
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,25 +3,43 @@ import std/sequtils | |
import std/options | ||
import std/random | ||
|
||
# workaround for https://github.com/nim-lang/Nim/issues/16360 | ||
proc rand(r: var Rand, max: uint64): uint64 = | ||
if max == 0: | ||
return 0 | ||
elif max == uint64.high: | ||
return r.next() | ||
else: | ||
var iters = 0 | ||
while true: | ||
let x = next(r) | ||
# avoid `mod` bias | ||
if x <= uint64.high - (uint64.high mod max) or iters > 20: | ||
return x mod (max + 1) | ||
else: | ||
inc iters | ||
|
||
func rand*(r: var Rand, x: Slice[BigInt]): BigInt = | ||
## Return a random `BigInt`, within the given range, using the given state. | ||
assert(x.a <= x.b, "invalid range") | ||
if x.a == x.b: | ||
return x.a | ||
let | ||
spread = x.b - x.a | ||
# number of bits *not* including leading bit | ||
nbits = spread.fastLog2 | ||
# number of limbs to generate completely randomly | ||
nFullLimbs = max(nbits div 32 - 1, 0) | ||
# highest possible value of the top two limbs. | ||
hi64Max = (spread shr (nFullLimbs*32)).toInt[:uint64].get() | ||
hi64Max = (spread shr (nFullLimbs * 32)).toInt[:uint64].get() | ||
while true: | ||
# these limbs can be generated completely arbitrarily | ||
var limbs = newSeqWith(nFullLimbs, r.rand(uint32.low..uint32.high)) | ||
var limbs = newSeqWith(nFullLimbs, uint32(r.next() and uint32.high)) # work around https://github.com/nim-lang/Nim/issues/16360 | ||
# generate the top two limbs more carefully. This all but guarantees | ||
# that the entire number is in the correct range | ||
let hi64 = r.rand(uint64.low..hi64Max) | ||
limbs.add(cast[uint32](hi64)) | ||
limbs.add(cast[uint32](hi64 shr 32)) | ||
let hi64 = r.rand(hi64Max) | ||
limbs.add(uint32(hi64 and uint32.high)) | ||
limbs.add(uint32(hi64 shr 32)) | ||
Comment on lines
+40
to
+42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This works by generating a 64-bit number. I am surprised that this works well on a 32-bit architecture. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why wouldn't it? 32 bit architectures support 64 bit numbers perfectly well, they're just slower (because they take up two memory locations). |
||
result = initBigInt(limbs) | ||
if result <= spread: | ||
break | ||
|
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.
We might want to drop support for 1.4.8.
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 wouldn't mind that, 1.4 has quite some bugs (#59, #93, #94) and doesn't receive backports anymore.
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.
+1 for dropping 1.4.x
It can also be part of a separate PR if you will. Don't forget to also bump minimal supported version in the
.nimble
file.