989 Commits

Author SHA1 Message Date
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
Josh Stone
089b86a513 Start the bump to 0.2 2018-02-23 17:22:12 -08:00
Josh Stone
f6568291ab
Merge pull request #21 from Robbepop/master
Add apint to README as another alternative
2018-02-15 12:19:32 -08:00
Hero Bird
07997b1989 add apint to README as another alternative
The ApInt crate is a pure rust implementation for arbitrary fixed bitwidth modulo arithmetics of integers with a focus on correctness and efficiency - especially for smaller bit widths. It features a generic signless `ApInt` as well as signed counterparts `Int` (signed int) and `UInt` (unsigned int) that are thin wrappers around it. The implementation is unfinished in some parts but that should be fixed over time.
2018-02-15 14:57:44 +01:00
bors[bot]
468a28df6d Merge #20
20: Note a few alternative crates in README.md r=cuviper a=cuviper

This presents a table of some common alternatives to this crate which may have better performance.  I'm not including any specific performance comparisons, since that will surely vary on different workloads, and will change as each crate evolves.  I want to keep this impartial, listing only simple objective facts about each.  Corrections welcome!

cc crate owners: @Aatch, @doomrobo, @fizyk20, @tspiteri
2018-02-10 02:15:13 +00:00
Josh Stone
e65c9f64a4 mention gmp-mpfr-sys only indirectly 2018-02-09 14:05:34 -08:00