Tracking Issue for bigint helper methods (original) (raw)
Feature gate: #![feature(bigint_helper_methods)]
This is a tracking issue for the following methods on integers:
carrying_addborrowing_subcarrying_mulcarrying_mul_addwidening_mul
These methods are intended to help centralise the effort required for creating efficient big integer implementations, by offering a few methods which would otherwise require special compiler intrinsics or custom assembly code in order to do efficiently. They do not alone constitute big integer implementations themselves, but are necessary building blocks for a larger implementation.
Public API
// On unsigned integers:
/// self * rhs (wide multiplication, same as self.carrying_mul(rhs, 0))
const fn widening_mul(self, rhs: Self) -> (Self, Self);
// On signed integers:
/// self + rhs + carry (full adder)
const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool);
/// self - rhs - carry (full "subtractor")
const fn borrowing_sub(self, rhs: Self, carry: bool) -> (Self, bool);
Stabilized as part of 1.91, but not yet const stable:
// On unsigned integers:
/// self + rhs + carry (full adder)
const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool);
/// self - rhs - carry (full "subtractor")
const fn borrowing_sub(self, rhs: Self, carry: bool) -> (Self, bool);
/// self * rhs + carry (multiply-accumulate)
const fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self);
/// self * rhs + carry (multiply-accumulate-carry)
const fn carrying_mul_add(self, rhs: Self, addend: Self, carry: Self) -> (Self, Self);
Steps / History
widening_mulRFC: widening_mul rfcs#2417- Initial implementation of
carrying_add,borrowing_sub,carrying_mul, andwidening_mulAdd carrying_add, borrowing_sub, widening_mul, carrying_mul methods to integers #85017 - Remove implementations on signed types Remove bigint_helper_methods for *signed* types #90848 per discussion in Signed carry carrying_add in bigint_helper_methods #90541
- Add new
carrying_addandborrowing_subon signed types: Reimplement carrying_add and borrowing_sub for signed integers. #93873 - Add a compiler intrinsic to back bigint_helper_methods #133663
- Add assembly tests to ensure this keeps doing the right thing
- One for
carrying_addwas added in Fix chaining carrying_adds #133674
- One for
- Clarify documentation
("without the ability to overflow" can be confusing.) - Final commenting period (FCP)
- Partial Stabilization PR Partial-stabilize the basics from bigint_helper_methods #144494
Unresolved Questions
- Should these be implemented using compiler intrinsics? LLVM currently has no equivalents, so, we'd have to custom-build some.
- Should an alternative API be provided for
widening_multhat simply returns the next-larger type? What would we do foru128/i128? - What should the behaviour be for signed integers? Should there be implementations for signed integers at all?
- Is the "borrowing" terminology worth it for subtraction, or should we simply call that "carrying" as well for consistency?
- Are there other methods that should be added in addition to the existing ones?