Skip to content

Commit

Permalink
Test on i386
Browse files Browse the repository at this point in the history
Update CI
  • Loading branch information
konsumlamm committed Dec 3, 2023
1 parent ed8be08 commit 337fa7b
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 13 deletions.
35 changes: 32 additions & 3 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,48 @@ jobs:
- run: echo "commit message doesn't contain '[skip ci]'"

test:
needs: before
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
nim-version:
- '1.4.8'
- '1.6.12'
- '1.6.16'
- '2.0.0'
- 'devel'
needs: before
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
- uses: jiro4989/setup-nim-action@v1
with:
nim-version: ${{ matrix.nim-version }}
- run: nimble install -y
- run: nimble test
- run: nimble checkExamples

i386:
needs: before
runs-on: ubuntu-latest
container:
image: i386/ubuntu:bionic
strategy:
fail-fast: false
matrix:
nim-version:
- '1.4.8'
- '1.6.16'
- '2.0.0'
steps:
- uses: actions/checkout@v1
- name: Setup
run: |
apt-get update -y
apt-get install -y curl gcc g++ git xz-utils
git config --global --add safe.directory /__w/bigints/bigints
- name: Install Nim
run: |
curl -sSf https://nim-lang.org/download/nim-${{ matrix.nim-version }}-linux_x32.tar.xz | tar -xJ
realpath nim-${{ matrix.nim-version }}/bin >> $GITHUB_PATH
- run: nimble install -y
- run: nimble test
- run: nimble checkExamples
1 change: 0 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ nimble install https://github.com/nim-lang/bigints

## Current limitations and possible enhancements

* not expected to work on 32 bit
* arithmetic operations such as addition, multiplication and division are not optimized for performance (e.g. [Karatsuba multiplication](https://en.wikipedia.org/wiki/Karatsuba_algorithm) is not implemented)


Expand Down
2 changes: 1 addition & 1 deletion src/bigints.nim
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func initBigInt*(vals: sink seq[uint32], isNegative = false): BigInt =
## Initializes a `BigInt` from a sequence of `uint32` values.
runnableExamples:
let a = @[10'u32, 2'u32].initBigInt
let b = 10 + 2 shl 32
let b = 10 + 2'u64 shl 32
assert $a == $b
result.limbs = vals
result.isNegative = isNegative
Expand Down
28 changes: 23 additions & 5 deletions src/bigints/random.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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))
result = initBigInt(limbs)
if result <= spread:
break
Expand Down
10 changes: 7 additions & 3 deletions tests/trandom.nim
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@ block: # check uniformity
doAssert(lo <= r)
doAssert(r <= hi)
total += r
let iBucket = (r-lo) div ((hi-lo) div initBigInt(nbuckets))
let iBucket = (r - lo) div ((hi - lo) div initBigInt(nbuckets))
buckets[iBucket.toInt[:int]().get()] += 1
for x in buckets:
doAssert(trials/nbuckets*0.5 < float(x))
doAssert(float(x) < trials/nbuckets*1.5)
doAssert(trials / nbuckets * 0.5 < float(x))
doAssert(float(x) < trials / nbuckets * 1.5)

block: # single element range
let x = 1234567890.initBigInt
for _ in 1..100:
doAssert rand(x..x) == x

0 comments on commit 337fa7b

Please sign in to comment.