fizyk20 / rust-mpfr

MPFR bindings for Rust
MIT License
5 stars 3 forks source link

Adding mpfr_sum wrapper #2

Open wictory opened 9 years ago

wictory commented 9 years ago

Hi,

I would like to add an mpfr_sum wrapper and I would like some input on how to it should best be implemented.

I have two candidates with different caveats.

First I have a function which first creates a Vec<*const Mpfr> of pointers to mpfr_strptr:s. The downside with this is that the call requires O(n) memory, for summing n elements which could be huge.

pub fn sum_create_pointer_vector(input: &[&Mpfr]) -> Mpfr {
    unsafe {
        let mut top = Vec::with_capacity(input.len());
        for v in input {
            top.push(&v.mpfr as mpfr_srcptr);
        }
        let mut res = Mpfr::new();
        mpfr_sum(&mut res.mpfr, top.into_boxed_slice().as_ptr(), input.len() as c_ulong, mpfr_rnd_t::MPFR_RNDN);
        res
    }
}

Second I have a function which bravely unsafely casts a nice &[&Mpfr] into a *const mpfr_srcptr. This function is "correct" in the sense that the tests go through, but is not correct in the sense that it is making assumption which might not hold on other platforms or future versions of the language/compiler/mpfr library. The function brakes without compiler error if another field is added the Mpfr type.

pub fn sum_possibly_unsafe(input: &[&Mpfr]) -> Mpfr {
    let input_p = (*input).as_ptr() as *const mpfr_srcptr;
    unsafe {
        let mut res = Mpfr::new();
        mpfr_sum(&mut res.mpfr, input_p, input.len() as c_ulong, mpfr_rnd_t::MPFR_RNDN);
        res
    }
}

I have a branch in my repo with the code and tests if you would like to check it out further.

wictory commented 9 years ago

The returned Mpfr need to be initiated with new2(max(values in input)).

fizyk20 commented 9 years ago

I think I'd go with the first approach. The second one looks too much like a "dirty hack" to me and indeed could easily break. The O(n) memory requirement also isn't that bad, I think, considering that it is only an array of pointers (so max. 8 bytes per element).