ISO/IEC JTC1 SC22 WG21 P0104R0 - 2015-09-27
Lawrence Crowl, Lawrence@Crowl.org
Introduction
Problem
Solution
Definition of Word
Multi-Word Types
Subarray by Word Operations
Subarray by Subarray Operations
Open Issues
When the largest integer type is too small for an application domain, one must use a larger type.
Multi-word integer operations are a necessary component of many higher-level types, such as those that appear later in the document.
The work for multi-word integer operations is tedious. For division it is also complicated. It is better to do that work once.
We propose a template for multi-word integer types that behave like built-in types. While built-in types often have insecure semantics, they are also efficient and well understood. Some programmers will prefer to use these types directly, but we also expect these types to be used as implementation tools for higher-level types.
We also propose a set of multi-word integer operations based on pointers and counts. This low-level interface is intended as an implementation tool for higher level operations and types, including those mentioned above. These operations can be built upon the wide operations presented in P0103r0 Overflow-Detecting and Double-Wide Arithmetic Operations.
Within this document, we use S
to refer to a signed word
and U
to refer to an unsigned word.
A word is the type provided by LARGEST_SINGLE_WIDE_ALL
and defined in
P0103r0
Overflow-Detecting and Double-Wide Arithmetic Operations.
We obtain a multi-word integer type with one of the following templates.
template<int words> multi_int;
template<int words> multi_uint;
The multi_int
type uses a two's complement representation.
The following multi-word operators take two multi-word arguments of arbitrary size and sign. The result type is a promoted type as specified for built-in integers.
~ * / % + - < > <= >= & | ^
= *= /= %= += -= < > <= >= &= |= ^=
The following multi-word operators take a left-hand multi-word argument (of arbitrary size and sign) and a right-hand integer argument. The result type is the type of the left-hand argument.
<< >> <<= >>=
All types implicitly convert to bool
via the normal rules.
Functions return by value. Programmers should consider the composite operation and assignment operators.
We provide the following operations. These operations are not intended to provide complete multi-word operations, but rather to handle subarrays with uniform operations. Higher-level operations then compose these operations into a complete operation.
U unsigned_subarray_addin_word U* multiplicand, int length, U addend );
Add the word addend
to the multiplicand
of length length
,
leaving the result in the multiplicand
.
The return value is any carry out from the accumulator
.
U unsigned_subarray_add_word U* summand, const U* augend, int length, U addend );
Add the addend
to the augend
of length length
writing the result to the summand
,
which is also of length length
.
The return value is any carry out from the summand
.
U unsigned_subarray_mulin_word U* product, int length, U multiplier );
Multiply the product
of length length
by the multiplier
,
leaving the result in the product
.
The return value is any carry out from the product
.
U unsigned_subarray_mul_word U* product, U* multiplicand, int length, U multiplier );
Multiply the multiplicand
of length length
by the multiplier
writing the result to the product
,
which is also of length length
.
The return value is any carry out from the product
.
U unsigned_subarray_accmul_word U* accumulator, U* multiplicand, int length, U multiplier );
Multiply the multiplicand
of length length
by the multiplier
adding the result to the accumulator
,
which is also of length length
.
The return value is any carry out from the accumulator
.
For each of the two add operations above, there is a corresponding subtract operation.
For each of the seven operations above (add+sub+mul), there is a corresponding signed operation. The primary difference between the two is sign extension.
For each of the fourteen operations in the section above,
there is a corresponding operation where the 'right-hand' argument
is a pointer to a subarray,
which is also of length length
.
There are as yet no definitions for subarray division.