-
Notifications
You must be signed in to change notification settings - Fork 189
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
Conversation
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 <[email protected]>
Ah, sorry, I didn't update the benchmarks for the new |
There was a problem hiding this 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; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 <[email protected]>
So, I've add a new |
Great, I'd be happy to. I already have a draft for the |
Closing in favor of #56. |
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 <[email protected]>
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 toBigInt
andBigUint
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
withThreadRng
in order to be able to run it.