794 Commits

Author SHA1 Message Date
bors[bot]
d449f32bd0 Merge #44
44: Add basic conversions for i128 and u128 r=cuviper a=cuviper



Co-authored-by: Josh Stone <cuviper@gmail.com>
2018-05-16 19:34:23 +00:00
Josh Stone
c6bce8a130 test i128 only on newer rustc 2018-05-16 12:19:47 -07:00
Josh Stone
04252b7716 Add basic conversions for i128 and u128 2018-05-15 18:01:14 -07:00
Josh Stone
275ba23cee chmod -x benches/factorial.rs 2018-05-14 23:04:37 -07:00
bors[bot]
79e5aa9dd7 Merge #43
43: Merge num-bigint-0.1.x and update pending release notes r=cuviper a=cuviper



Co-authored-by: Josh Stone <cuviper@gmail.com>
Co-authored-by: bors[bot] <bors[bot]@users.noreply.github.com>
2018-05-14 20:43:31 +00:00
Josh Stone
fee644e91f Update release notes toward 0.2x 2018-05-14 13:39:35 -07:00
Josh Stone
b374f9ac92 Merge branch 'num-bigint-0.1.x' into master 2018-05-14 13:01:51 -07:00
Josh Stone
2d37c0bb10 Mention the crate comparisons in 0.1.44 too
... if only to give more complete author credits for the release.
2018-05-14 12:06:50 -07:00
bors[bot]
5185cc2b8b Merge #42
42: Add a special case for single-digit divisors r=cuviper a=cuviper

It was pointed out in the blog post [Big Integers in Zig] that we don't
have a special case in `num-bigint` for single-digit divisors.  While
you can already get this optimization by dividing directly by `u32`,
it's easy to make small `BigUint` divisors work like this too.

    $ cargo benchcmp baseline single-div
     name                   baseline ns/iter  single-div ns/iter  diff ns/iter   diff %  speedup
     factorial_div_biguint  5,638,353         1,005,488             -4,632,865  -82.17%   x 5.61

`BigInt` will also gain from this, since it uses `BigUint` division
internally.

Running [zig-bn's facdiv-rs] shows a nice improvement too.  My i7-7700K
with Rust 1.26 goes from 4.15 seconds to just 0.65 -- a 6.38x speedup!

[Big Integers in Zig]: https://tiehuis.github.io/big-integers-in-zig#division-test-single-limb
[zig-bn's facdiv-rs]: https://github.com/tiehuis/zig-bn/tree/master/bench/facdiv/crate-facdiv-rs


Co-authored-by: Josh Stone <cuviper@gmail.com>
2018-05-14 18:41:57 +00:00
Josh Stone
10e00ff66a Release 0.1.44 2018-05-14 11:24:39 -07:00
Josh Stone
f44bd0aee2 Add a special case for single-digit divisors
It was pointed out in the blog post [Big Integers in Zig] that we don't
have a special case in `num-bigint` for single-digit divisors.  While
you can already get this optimization by dividing directly by `u32`,
it's easy to make small `BigUint` divisors work like this too.

    $ cargo benchcmp baseline single-div
     name                   baseline ns/iter  single-div ns/iter  diff ns/iter   diff %  speedup
     factorial_div_biguint  5,638,353         1,005,488             -4,632,865  -82.17%   x 5.61

`BigInt` will also gain from this, since it uses `BigUint` division
internally.

Running [zig-bn's facdiv-rs] shows a nice improvement too.  My i7-7700K
with Rust 1.26 goes from 4.15 seconds to just 0.65 -- a 6.38x speedup!

[Big Integers in Zig]: https://tiehuis.github.io/big-integers-in-zig#division-test-single-limb
[zig-bn's facdiv-rs]: https://github.com/tiehuis/zig-bn/tree/master/bench/facdiv/crate-facdiv-rs
2018-05-14 11:24:32 -07:00
bors[bot]
351ea5f2b1 Merge #41
41: Implement assignment operators for BigInt r=cuviper a=cuviper

All of these operators were already implemented for `BigUint`, so
now `BigInt` support the same use.

Closes #7.

Co-authored-by: Josh Stone <cuviper@gmail.com>
2018-05-12 00:31:28 +00:00
Josh Stone
96c1d69279 Implement assignment operators for BigInt
All of these operators were already implemented for `BigUint`, so
now `BigInt` support the same use.

Closes #7.
2018-05-09 16:36:29 -07:00
Josh Stone
dd4081721f sources shouldn't be executable 2018-05-09 16:18:56 -07:00
bors[bot]
86de320b63 Merge #39
39: Make it explicit that serialization is in u32 r=cuviper a=cuviper

Add explicit type annotations to make sure we serialize `BigUint` like a
`Vec<u32>`.  If we ever change the internal representation, we still
need to remain compatible with serialized data.

Also, deserializing `BigUint` and `BigInt` now uses their normal
constructor methods, to make sure they are normalized.  We shouldn't
assume that all incoming data is already well-formed.

Co-authored-by: Josh Stone <cuviper@gmail.com>
2018-05-03 19:55:25 +00:00
Josh Stone
087c4ecfd6 Add serde tests 2018-05-03 12:39:15 -07:00
Josh Stone
f683b9d821 Make it explicit that serialization is in u32
Add explicit type annotations to make sure we serialize `BigUint` like a
`Vec<u32>`.  If we ever change the internal representation, we still
need to remain compatible with serialized data.

Also, deserializing `BigUint` and `BigInt` now uses their normal
constructor methods, to make sure they are normalized.  We shouldn't
assume that all incoming data is already well-formed.
2018-05-02 12:48:21 -07:00
bors[bot]
e22271cbc5 Merge #38
38: Remove big_digit::* from the public API r=cuviper a=cuviper

The *idea* of `big_digit` and its type aliases is that we may someday
use something other than `u32` in the representation, perhaps even
different sizes for different targets.  That's still a possibility, but
I think it's not really feasible to expose this variation in the public
API.  Calling `BigUint::from_slice([1, 2, 3])` is only meaningful if you
know what that size is, and users can't really alternate this kind of
thing based on a type definition.  So for now, we just commit to `u32`
units in the public API, no matter what we may do internally.

This removal is a breaking change, part of the 0.2 semver bump.  If I'm
wrong and somebody can show a compelling use case for `big_digit`, we
can always add things back into the public API later.

Co-authored-by: Josh Stone <cuviper@gmail.com>
2018-05-01 04:34:15 +00:00
Josh Stone
a849284320 Remove big_digit::* from the public API
The *idea* of `big_digit` and its type aliases is that we may someday
use something other than `u32` in the representation, perhaps even
different sizes for different targets.  That's still a possibility, but
I think it's not really feasible to expose this variation in the public
API.  Calling `BigUint::from_slice([1, 2, 3])` is only meaningful if you
know what that size is, and users can't really alternate this kind of
thing based on a type definition.  So for now, we just commit to `u32`
units in the public API, no matter what we may do internally.

This removal is a breaking change, part of the 0.2 semver bump.  If I'm
wrong and somebody can show a compelling use case for `big_digit`, we
can always add things back into the public API later.
2018-04-27 23:52:41 -07:00
bors[bot]
7424bbe0ea Merge #37
37: Change ParseBigIntError to an opaque struct r=cuviper a=cuviper
2018-03-27 20:13:15 +00:00
Josh Stone
f086bb0353 Change ParseBigIntError to an opaque struct 2018-03-26 22:28:55 -07:00
bors[bot]
007da2add9 Merge #26
26: two's-complement logic operations on BigInt r=cuviper a=tspiteri

This commit adds the following impls, giving results equivalent to what would be expected with two's complement.

* `impl Not for BigInt`
* `impl BitAnd<&BigInt> for BigInt`, `impl BitAndAssign<&BigInt> for BigInt`
* `impl BitOr<&BigInt> for BigInt`, `impl BitOrAssign<&BigInt> for BigInt`
* `impl BitXor<&BigInt> for BigInt`, `impl BitXorAssign<&BigInt> for BigInt`

I also added some tests. There is most probably some room for optimization, but the bitwise operations all operate in place using a single pass.

I did not add other implementations such as `impl BitAnd<BigInt> for BigInt`, those can be done later.

Edit: Fixes #13
2018-03-06 06:22:04 +00:00
Josh Stone
ec0113ea3e impl<'a> Not for &'a BigInt 2018-03-05 22:03:13 -08:00
Trevor Spiteri
959130e7b9 val/ref forwarding for BigInt bitwise operations 2018-03-04 11:35:00 +01:00
Trevor Spiteri
c5d6c2c691 crate-visible IntDigits trait for common BigUint and BigInt access 2018-03-04 11:34:47 +01:00
Trevor Spiteri
e005dcc942 add tests for two's-complement bitwise operations 2018-03-04 10:22:29 +01:00
Trevor Spiteri
b16359cd22 two's-complement bitwise operations on BigInt 2018-03-04 10:21:14 +01:00
bors[bot]
6d5d24066b Merge #35
35: avoid over-allocation for bitwise and of references r=cuviper a=tspiteri

For `&BigUint & &BigUint`, clone the smaller value to avoid over-allocation, as the result will have a length less than or equal to the minimum length of the operands.
2018-03-04 00:30:25 +00:00
bors[bot]
35fac74436 Merge #34
34: do not zero-extend for addition when val is shorter than ref r=cuviper a=tspiteri

For `short_val + long_ref`, `long_ref + short_val` and `long_ref - short_val`, the current code extends the short value with zeros and then performs the operation. Instead, this commit splits the addition/subtraction into two parts, the lower and the higher parts. After performing the addition/subtraction on the low part, the short value is extended with the high part of the long reference, and the intermediate carry/borrow is then added to/subtracted from the high part.
2018-03-04 00:15:38 +00:00
Trevor Spiteri
e70e453ba6 avoid over-allocation for bitwise and of references 2018-03-03 14:50:16 +01:00
Trevor Spiteri
993494ba2d do not zero-extend for addition when val is shorter than ref 2018-03-03 14:40:48 +01:00
bors[bot]
ccd54a1cc0 Merge #28
28: Implement is_one for BigUint and BigInt. r=cuviper a=clarcharr

Won't work until a newer version of `num-traits` is pushed, but I figured I'd offer these now.
2018-03-03 05:09:07 +00:00
Josh Stone
12498b20fa bump to num-traits 0.2.1 2018-03-02 21:07:22 -08:00
bors[bot]
d6fc7bc733 Merge #32
32: Avoid an extra allocation in UpperHex r=cuviper a=cuviper
2018-03-02 19:40:45 +00:00
Josh Stone
b53a797dcd Avoid an extra allocation in UpperHex 2018-03-02 11:02:53 -08:00
Clar Charr
f91db6bea4 Implement is_one for BigUint and BigInt. 2018-02-27 14:44:01 -05:00
bors[bot]
1cf2196e78 Merge #27
27: Chop the tests up r=cuviper a=cuviper

The test modules were getting huge, and some of its functions were
actually a huge amount of code due to macros, causing tests to take a
long time just to compile.  They are now separated into a few different
tests, and the scalar macros especially are now expanded more sparingly
in just a few `check()` functions.

Test compile times for me went from about 25 seconds to 1.5s in debug
mode, and from 300 seconds (!) to about 8s in release mode.
2018-02-27 06:25:34 +00:00
Josh Stone
8964eb9887 Chop the tests up
The test modules were getting huge, and some of its functions were
actually a huge amount of code due to macros, causing tests to take a
long time just to compile.  They are now separated into a few different
tests, and the scalar macros especially are now expanded more sparingly
in just a few `check()` functions.

Test compile times for me went from about 25 seconds to 1.5s in debug
mode, and from 300 seconds (!) to about 8s in release mode.
2018-02-26 22:13:25 -08:00
bors[bot]
01cf35ae3c Merge #22
22: Implementation of std::iter::{Product, Sum} r=cuviper a=dodomorandi

This PR is relative to the [issue 4](https://github.com/rust-num/num-bigint/issues/4). This is a
very simple implementation, based on two macros. Maybe a more elegant
solution is possible for these, feel free to suggest.

Two tests for both `BigInt` and `BigUInt` have been added, one relative
to the `Sum`, the other to the `Product`.
2018-02-27 01:20:59 +00:00
Josh Stone
60910893ff rust-1.15: avoid Self in constraint 2018-02-26 17:11:48 -08:00
Edoardo Morandi
d6fa4ac632 Generic implementation for Sum and Product
The succestion came from @cupiver, and it was simple and elegant. Now it
should be possible to use `std::iter::{Sum, Product}` with everything
that can be Add`-ed and `Mul`-tiplied _against_ `BigInt` and `BigUint`
2018-02-26 16:55:43 -08:00
Edoardo Morandi
68600a3def Implementation of std::iter::{Product, Sum}
This is relative to the
[issue 4](https://github.com/rust-num/num-bigint/issues/4). This is a
very simple implementation, based on two macros. Maybe a more elegant
solution is possible for these, feel free to suggest.

Two tests for both `BigInt` and `BigUInt` have been added, one relative
to the `Sum`, the other to the `Product`.
2018-02-26 16:55:43 -08:00
bors[bot]
65214f7b28 Merge #24
24: Update rand and serde; drop rustc-serialize r=cuviper a=cuviper

Fixes #9.
2018-02-27 00:28:37 +00:00
bors[bot]
1c192733bf Merge #25
25: do not convert carry/borrow to/from DoubleBigDigit r=cuviper a=tspiteri

Currently `adc`, `sbb`, `mac_with_carry` and `mul_with_carry` in *algorithms.rs* take the carry/borrow as a `BigDigit`, then convert it every iteration to `DoubleBigDigit` for the addition/subtraction. With this commit, a kind of accumulator takes place of the carry and borrow. It is stored as a `DoubleBigDigit` and not converted to/from `BigDigit` at all. For subtraction, the accumulator is stored as a `SignedDoubleBigDigit` in order to enable arithmetic right shift and to be able to easily handle subtraction.

I'm not very familiar with the crate's benchmarking methods. I wrote some hacky benchmarks for a quick comparison. Basically, just have two vectors `[10000000, 0, !0, 1, 29999999]` and `[10, !0, 5, 234, 23]`, and add/subtract/multiply a couple hundred times. I saw these gains:
```
running 6 tests
test tests::bench_changed_add  ... bench:         992 ns/iter (+/- 58)
test tests::bench_changed_mul  ... bench:       9,667 ns/iter (+/- 185)
test tests::bench_changed_sub  ... bench:       1,497 ns/iter (+/- 38)
test tests::bench_original_add ... bench:       1,085 ns/iter (+/- 50)
test tests::bench_original_mul ... bench:       9,838 ns/iter (+/- 284)
test tests::bench_original_sub ... bench:       1,642 ns/iter (+/- 14)
```

The gains are not very large, after all only a couple of assembly instructions per iteration are saved. I also do not know whether other architectures than x86_64 are affected similarly or in the opposite direction.

The change in the parameter from `&mut BigDigit` to `&mut DoubleBigDigit` is automatically handled in other files, as carry is simply initialized as zero and compared to zero at the end, with the type being inferred.
2018-02-26 21:32:35 +00:00
Trevor Spiteri
113e939539 do not convert carry/borrow to/from DoubleBigDigit 2018-02-25 20:46:59 +01:00
Josh Stone
e89c48081f Update rand and serde; drop rustc-serialize 2018-02-24 01:28:57 -08:00
bors[bot]
66f9d0e8f6 Merge #8
8: Make Shr for negative BigInt round down, like primitives do r=cuviper a=cuviper

Primitive integers always round down when shifting right, but `BigInt`
was effectively rounding toward zero, because it just kept its sign and
used the `BigUint` magnitude rounded down (always toward zero).

Now we adjust the result of shifting negative values, and explicitly
test that it matches the result for primitive integers.

Fixes #1.
2018-02-24 08:49:21 +00:00
Josh Stone
b315c01eb1 Add a release note for Shr 2018-02-24 00:41:06 -08:00
Josh Stone
87fe608570 Make Shr for negative BigInt round down, like primitives do
Primitive integers always round down when shifting right, but `BigInt`
was effectively rounding toward zero, because it just kept its sign and
used the `BigUint` magnitude rounded down (always toward zero).

Now we adjust the result of shifting negative values, and explicitly
test that it matches the result for primitive integers.
2018-02-24 00:40:59 -08:00
bors[bot]
5e389ca670 Merge #23
23: Start the bump to 0.2 r=cuviper a=cuviper

rustc 1.15.0 is the new minimum.
2018-02-24 01:42:06 +00:00