mhogrefe / malachite

An arbitrary-precision arithmetic library for Rust.
GNU Lesser General Public License v3.0
448 stars 17 forks source link

Read from binary string, like mpz_import ? #31

Closed XavDesbordes closed 8 months ago

XavDesbordes commented 8 months ago

Hi, I have a binary string that is retrieved from a Vec<u8> that I would like to inject in a Rational numerator.

In C++, I use the function mpz_import which is able to convert any binary input into a number. That binary string doesn't necessarily contains number '0' to '9'. Instead, it can be a binary string that I want converted to a number. It is the raw data that interest me as a number.

I searched but couldn't find a function approaching this need. The from_string_base doesn't make it for the above reason.

I want to consider any input (binary text, wikipedia page for example) as a number using its raw binary data.

Any way to make this happen ?

Thanks

XavDesbordes commented 8 months ago

Natural::from_limbs_asc(&slice); did the trick !

mhogrefe commented 8 months ago

Hi,

I assume you did some preprocessing of your data to make it work with from_limbs_asc. There are more direct ways to do it: using from_bits_asc, like this:

use malachite::num::logic::traits::BitConvertible;

let n = Natural::from_bits_asc(bits.iter().map(|&b| b == 1));

or using from_power_of_2_digits_asc, like this:

use malachite::num::conversion::traits::PowerOf2Digits;

let n = Natural::from_power_of_2_digits_asc(1, bits.iter().cloned());

Both methods should be very fast.

Finally, if you want to modify the numerator of an existing Rational, you can use mutate_numerator.

Let me know if you have any questions.

XavDesbordes commented 8 months ago

Thanks, I will try that. In the meantime, I could compare the perf with rug/gmp for the same code and the difference for flooring rationals or dividing them is huge (seconds of difference for the same input ( size of 500k+, release mode); I know it's not scientific but for random data of that size this is what comes out). I will investigate. GMP source code is rapidly complex so I am not sure I can find something relevant quickly though.. except optimized assembly instructions maybe.. But thanks for this great project

mhogrefe commented 8 months ago

You're welcome!

Currently rug/GMP is still faster than Malachite, particularly for integer multiplication, and everything uses integer multiplication. At some point I'll investigate this more deeply. As you say, it might come down to optimized assembly.