How to parse a string into a Float with high precision using the rug crate in Rust?

How to parse a string into a Float with high precision using the rug crate in Rust?

i'm currently using the rug crate in Rust to work with high precision numbers (specifically Float). I need to parse a string into a Float with very high precision, and I'm encountering an issue with the Float::parse method. It returns a Result<ParseIncomplete, ParseFloatError>. How can I properly extract the parsed Float from the Result?"

I'm working on a Rust project that involves high-precision floating-point arithmetic, and I've chosen to use the rug crate for its Float type, which offers arbitrary precision. I'm encountering a couple of issues that I need help with.

First, when I use the parse method on the Float type, I get a Result that, when successful, contains a ParseIncomplete value. This ParseIncomplete is a tuple struct that includes the parsed Float and the remainder of the input string. I'm finding this a bit difficult to work with and I'm not sure I'm handling it correctly.

Here's a snippet of my code:

let target_value = match Float::parse(&opt.target_value) {
    Ok((f, _)) => f,
    Err(e) => return Err(e),
};

Second, I'm facing an issue when trying to perform arithmetic operations where Float needs to interact with standard f64 numbers. For instance, in this line of code:

let result = (target_value * 3.0 / 4.0).cbrt();

I'm getting type errors because Float and f64 aren't directly compatible.

I tried using parse_complete, which returns the Float directly, but I'm still stuck on the arithmetic issue. Here's how I used parse_complete:

let target_value = Float::parse_complete(&opt.target_value)?;

My questions are:

How can I properly handle the result of Float::parse? Is there a better way to extract the parsed Float value and ignore the remainder of the string? How can I perform arithmetic operations that involve both Float and f64 numbers? Any guidance would be greatly appreciated. Thank you!

Regarding the result of Float::parse: Have you taken a look at the relevant section in the documentation about “incomplete values” yet that the Float::parse docs link to? Those docs themself also speficy more precisely what traits the returned ParseIncomplete type will implement, so that you know how you can use it:

The following are implemented with the unwrapped returned incomplete-computation value as Src:

How I understand this statement is that you’re supposed to read “Src” as meaning the ParseIncomplete type here.

Admitted, the documentation is a bit complicated, as ParseIncomplete seems to be a type with hidden documentation (public type in a private module, I assume), which may be motivated by the desire not to make the type name a stable part of the API. (Also it’s an enum, and I assume this helps hiding the constructors, but that could’ve been solved by wrapping it in a struct with private fields.)

Testing this kind of expression with target_value: Float only gives me a type annotations needed error because the compiler isn’t sure whether the numbers should be f64 or f32, and with a bit of a type hint it works fine:

let result = (target_value * 3.0_f64 / 4.0_f64).cbrt();

Also, I’d probably calculate the 3/4 part first, as that’s a cheap compilation and the result is accurate anyways, but that’s unrelated to your question.

1 Like