Skip to content
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

Implement sqrt for BigInt and BigUint #51

Closed
wants to merge 2 commits into from

Conversation

mancabizjak
Copy link
Contributor

Related to #3.

I needed to calculate square root of a big integer in the project I'm working on, so I thought maybe this can be useful to others as well.

This PR adds sqrt() method for calculating square root of a non-negative integer to BigInt and BigUint types. Square root is obtained via Newton's method, with a reasonable initial guess to improve performance.

Benchmark is included, although I had to replace the implementation of StdRng with ThreadRng in order to be able to run it.

This commit adds sqrt method for calculating square root of a
non-negative integer to BigInt and BigUint types. Square root
is obtained via Newton's method with a good initial guess to
improve performance. Tests and benchmark were also added.

Signed-off-by: Manca Bizjak <manca.bizjak@xlab.si>
@cuviper
Copy link
Member

cuviper commented May 30, 2018

Benchmark is included, although I had to replace the implementation of StdRng with ThreadRng in order to be able to run it.

Ah, sorry, I didn't update the benchmarks for the new rand. I'll do a separate PR to clean that up.

Copy link
Member

@cuviper cuviper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be nice to have, although I think I'd still like it to be a generic method of Integer, which we'd then optimize here. I had a branch I was toying with somewhere -- let me see if I can get that on num-integer.

src/biguint.rs Outdated
loop {
s = u;
let q = self.div_floor(&s);
let t: BigUint = &s + &q;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need q after this, so adding &s + q by value will let it reuse that memory allocation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, fixed.

src/biguint.rs Outdated
let t: BigUint = &s + &q;

// Compute the candidate value for next iteration
u = t.div_floor(&two);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason you're using div_floor instead of the / operator? With the operator you can also use integer literals, like t / 2u32. But even more, t >> 1 is probably faster.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No reason whatsoever, it just slipped my mind it seems. I replaced the usage of div_floor with the / and >> operators as appropriate, and also replaced the lsh call with <<. Looks much cleaner now.

This commit cleans up implementation of the sqrt method on the
BigUint type. Method calls of div_floor and lsh were also replaced
with overloaded operators.

Signed-off-by: Manca Bizjak <manca.bizjak@xlab.si>
@cuviper
Copy link
Member

cuviper commented Jul 6, 2018

So, I've add a new Roots trait, with sqrt, cbrt, and nth_root, which I'd like to get implemented for num-bigint. Are you interested in doing this? If not, I'll just merge your PR and then add Roots separately. We can either keep the inherent methods that then call Roots or vice versa, to let users call the methods without importing the trait.

@mancabizjak
Copy link
Contributor Author

Great, I'd be happy to. I already have a draft for the nth_root implementation but it needs a little polishing. Hopefully I'll have everything ready some time the following week.

@cuviper cuviper mentioned this pull request Jul 10, 2018
@mancabizjak
Copy link
Contributor Author

Closing in favor of #56.

bors bot added a commit that referenced this pull request Jul 19, 2018
56: Implement Roots for BigInt and BigUint r=cuviper a=mancabizjak

Supersedes #51 .

Since there is now a `Roots` trait with `sqrt`, `cbrt` and `nth_root` methods in the `num-integer` crate, this PR implements it for `BigInt` and `BigUint` types. I also added inherent methods on both types to allow the users access to all these functions without having to import `Roots`.

PS: `nth_root` currently  uses `num_traits::pow`. Should we perhaps wait for #54 to get merged, and then replace the call to use the new `pow::Pow` implementation on `BigUint`?

Co-authored-by: Manca Bizjak <manca.bizjak@xlab.si>
@mancabizjak mancabizjak deleted the impl-sqrt branch July 30, 2018 11:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants