Skip to content

Commit d49bafa

Browse files
committed
Test on i386
Update CI
1 parent b99fb99 commit d49bafa

File tree

5 files changed

+62
-12
lines changed

5 files changed

+62
-12
lines changed

.github/workflows/test.yaml

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,16 @@ jobs:
1414
- run: echo "commit message doesn't contain '[skip ci]'"
1515

1616
test:
17+
needs: before
1718
runs-on: ubuntu-latest
1819
strategy:
20+
fail-fast: false
1921
matrix:
2022
nim-version:
2123
- '1.4.8'
22-
- '1.6.12'
24+
- '1.6.16'
25+
- '2.0.0'
2326
- 'devel'
24-
needs: before
2527
steps:
2628
- uses: actions/checkout@v4
2729
- uses: jiro4989/setup-nim-action@v1
@@ -30,3 +32,30 @@ jobs:
3032
- run: nimble install -y
3133
- run: nimble test
3234
- run: nimble checkExamples
35+
36+
i386:
37+
needs: before
38+
runs-on: ubuntu-latest
39+
container:
40+
image: i386/ubuntu
41+
strategy:
42+
fail-fast: false
43+
matrix:
44+
nim-version:
45+
- '1.4.8'
46+
- '1.6.16'
47+
- '2.0.0'
48+
steps:
49+
- uses: actions/checkout@v1
50+
- name: Setup
51+
run: |
52+
apt-get update -y
53+
apt-get install -y curl gcc g++ git xz-utils
54+
git config --global --add safe.directory /__w/bigints/bigints
55+
- name: Install Nim
56+
run: |
57+
curl -sSf https://nim-lang.org/download/nim-${{ matrix.nim-version }}-linux_x32.tar.xz | tar -xJ
58+
realpath nim-${{ matrix.nim-version }}/bin >> $GITHUB_PATH
59+
- run: nimble install -y
60+
- run: nimble test
61+
- run: nimble checkExamples

readme.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ nimble install https://github.com/nim-lang/bigints
2626

2727
## Current limitations and possible enhancements
2828

29-
* not expected to work on 32 bit
3029
* 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)
3130

3231

src/bigints.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func initBigInt*(vals: sink seq[uint32], isNegative = false): BigInt =
3131
## Initializes a `BigInt` from a sequence of `uint32` values.
3232
runnableExamples:
3333
let a = @[10'u32, 2'u32].initBigInt
34-
let b = 10 + 2 shl 32
34+
let b = 10 + 2'u64 shl 32
3535
assert $a == $b
3636
result.limbs = vals
3737
result.isNegative = isNegative

src/bigints/random.nim

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,43 @@ import std/sequtils
33
import std/options
44
import std/random
55

6+
# workaround for https://github.com/nim-lang/Nim/issues/16360
7+
proc rand(r: var Rand, max: uint64): uint64 =
8+
if max == 0:
9+
return 0
10+
elif max == uint64.high:
11+
return r.next()
12+
else:
13+
var iters = 0
14+
while true:
15+
let x = next(r)
16+
# avoid `mod` bias
17+
if x <= uint64.high - (uint64.high mod max) or iters > 20:
18+
return x mod (max + 1)
19+
else:
20+
inc iters
21+
622
func rand*(r: var Rand, x: Slice[BigInt]): BigInt =
723
## Return a random `BigInt`, within the given range, using the given state.
824
assert(x.a <= x.b, "invalid range")
25+
if x.a == x.b:
26+
return x.a
927
let
1028
spread = x.b - x.a
1129
# number of bits *not* including leading bit
1230
nbits = spread.fastLog2
1331
# number of limbs to generate completely randomly
1432
nFullLimbs = max(nbits div 32 - 1, 0)
1533
# highest possible value of the top two limbs.
16-
hi64Max = (spread shr (nFullLimbs*32)).toInt[:uint64].get()
34+
hi64Max = (spread shr (nFullLimbs * 32)).toInt[:uint64].get()
1735
while true:
1836
# these limbs can be generated completely arbitrarily
19-
var limbs = newSeqWith(nFullLimbs, r.rand(uint32.low..uint32.high))
37+
var limbs = newSeqWith(nFullLimbs, uint32(r.next() and uint32.high)) # work around https://github.com/nim-lang/Nim/issues/16360
2038
# generate the top two limbs more carefully. This all but guarantees
2139
# that the entire number is in the correct range
22-
let hi64 = r.rand(uint64.low..hi64Max)
23-
limbs.add(cast[uint32](hi64))
24-
limbs.add(cast[uint32](hi64 shr 32))
40+
let hi64 = r.rand(hi64Max)
41+
limbs.add(uint32(hi64 and uint32.high))
42+
limbs.add(uint32(hi64 shr 32))
2543
result = initBigInt(limbs)
2644
if result <= spread:
2745
break

tests/trandom.nim

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,13 @@ block: # check uniformity
1414
doAssert(lo <= r)
1515
doAssert(r <= hi)
1616
total += r
17-
let iBucket = (r-lo) div ((hi-lo) div initBigInt(nbuckets))
17+
let iBucket = (r - lo) div ((hi - lo) div initBigInt(nbuckets))
1818
buckets[iBucket.toInt[:int]().get()] += 1
1919
for x in buckets:
20-
doAssert(trials/nbuckets*0.5 < float(x))
21-
doAssert(float(x) < trials/nbuckets*1.5)
20+
doAssert(trials / nbuckets * 0.5 < float(x))
21+
doAssert(float(x) < trials / nbuckets * 1.5)
2222

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

0 commit comments

Comments
 (0)