stencillogic/astro-float

Addition of specific values in `expr!` hangs astro_float

barafael opened this issue · 5 comments

While happily using this library, we noticed a program would hang in certain conditions and narrowed it down to this snippet:

use astro_float::{ctx::Context, expr, BigFloat, Consts, RoundingMode, Sign};

fn main() {
    let mut precision_context = Context::new(
        128,
        RoundingMode::ToEven,
        Consts::new().expect("Constants cache initialized"),
    );

    let x = BigFloat::from_raw_parts(
        &[9441246966859219331u64, 13943995520284385473u64],
        128,
        Sign::Pos,
        -5,
        true,
    );
    let y = BigFloat::from_raw_parts(
        &[145249953336295741u64, 9295997013522923649u64],
        128,
        Sign::Neg,
        -3,
        true,
    );

    println!("{}", expr!(y + x, &mut precision_context));
}

Version of astro-float:

astro-float = "0.7.1"

Platform is windows. Here are the compiler versions I can reproduce it with:

rustc 1.75.0-nightly (a2f5f9691 2023-11-02)
rustc 1.73.0 (cc66ad468 2023-10-03)

In your example numbers are constructed from raw parts, and both of them are inexact (last argument in BigFloat::from_raw_parts). As a result, when two inexact numbers are added, the result is also inexact. That means that expr! will try to achieve correct rounding by increasing the precision of the result until the least significant bit flips, which will never happen in this example. So, either the numbers should be marked as exact (BigFloat::set_inexact), or the rounding mode could be None if you don't care about correct rounding (a correctly rounded result differs just in the least significant bit).
Unfortunately, expr is not intelligent and does not analyze the expression you give it, so this kind of situation can happen.

So, I think this is a documentation issue.

@barafael As a follow up, it appears that potentially any BigFloat marked as inexact when passed as input to not only expr!, but also to some functions, e.g. acos can potentially hang the computation. So, I am going to change the behaviour of such functions and the macro expr! in such way that they will treat any argument of type BigFloat as exact. I think it will be less confusing and less error prone. Thank you for pointing to this problem.

Release 0.8.0 has been published that should cover this problem. More specifically: mechanism of correct rounding has been removed from the expr! macro completely.
Release notes https://github.com/stencillogic/astro-float/blob/main/RELEASE_NOTES.md

Thanks!