Skip to content
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

Feature Request: Ref type for {BigInt|BigUint} #283

Open
TennyZhuang opened this issue Sep 8, 2023 · 2 comments
Open

Feature Request: Ref type for {BigInt|BigUint} #283

TennyZhuang opened this issue Sep 8, 2023 · 2 comments

Comments

@TennyZhuang
Copy link

TennyZhuang commented Sep 8, 2023

Propose to introduce the BigIntRef and BigUintRef type, and the definition should be:

struct BigUintRef<'a> {
    data: &'a [BigDigit],
}
struct BigIntRef<'a> {
    sign: Sign,
    data: BigUintRef<'a>,
}

And implement all ops on them.

The feature is useful when we want to store a list of BigInt or BigUint in a flatten memory and apply op on them without a whole clone.

@cuviper
Copy link
Member

cuviper commented Sep 15, 2023

The internal layout ofBigDigits is an implementation detail, and I don't see how we could support arbitrary slices without exposing that. Plus, duplicating all ops on these ref types would be a large burden, and even more so if that also mixes operations with the normal non-ref types and primitive integers as operands.

It may be more feasible to support BigUint<A> and BigInt<A> for A: Allocator, once the standard library stabilizes those APIs for Vec<T, A>. Then we'd just be making our types more generic, and you could use things like &'a Bump for your flattened memory.

apply op on them without a whole clone.

For any ops that would work on such Ref types, can't you already just use &BigInt or &BigUint without cloning?

@akubera
Copy link

akubera commented Mar 18, 2024

For the BigDecimal crate I added a BigDecimalRef<'a> struct which wraps a &BigUint which has worked pretty well for me.

pub struct BigDecimalRef<'a> {
    sign: Sign,
    digits: &'a BigUint,
    scale: i64,
}

https://github.com/akubera/bigdecimal-rs/blob/5eb7c228dea390de538aa6d35eb84d76fbf8f9d7/src/lib.rs#L1242

All the (non-mutable) methods need to be duplicated for the Ref struct (or rather moved, as the &self -> BigDecimalRef is trivial, so they're just thin calls fn method(&self, ...) { self.to_ref().method(...) }

The suggested implementation would work:

#[derive(Clone,Copy)]
pub struct BigIntRef<'a> {
   sign: Sign,
   mag: BigUintRef<'a>,
}

#[derive(Clone,Copy)]
pub struct BigUintRef<'a> {
  data: &'a [BigDigit];
}

A mutable BigIntRef would allow (for example) a no-clone abs() method which changes the sign, leaving the digit data alone.

With such a ref struct, I'd be able to change my impl to:

pub struct BigDecimalRef<'a> {
    sign: Sign,
    digits: BigUintRef<'a>,
    scale: i64,
}

So the ref would contain the slice, rather than reference to the uint which contains the vector.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants