Int operations

The functions, types and constants described in this section are useful for dealing with Int objects. Two basic modes of operation are supported:

  1. Converting between Alore Int objects and fixed-precision C integer types, potentially causing overflow errors during conversions.
  2. Using only Alore Int objects to support arbitrary-precision arithmetic.

The first mode is usually sufficient, and when dealing with existing C interfaces, it is usually the only realistic approach. It also makes dealing with integer objects in C code relatively simple. Thus this mode is recommended unless arbitrary precision is specifically required. An overview of using this mode is given below:

  1. Convert input Alore objects to C integer types using functions such as AGetInt. If the inputs are out of range, a ValueError exception will be raised.
  2. Perform any calculations using C integer types such as int or AInt64, without having to use the Alore C API.
  3. Any integer result objects that are returned from functions or stored in Alore objects can be created from C integer types using functions such as AMakeInt.

This approach usually results in efficient and easy-to-understand code, since the number of API function calls is minimized. A major downside of this approach is the loss of Alore integer semantics, which are replaced with the often less desirable C semantics that include integer truncation and the limited range of integers.

See also: Operations described in sections Arithmetic operations and Comparison operations such as AAdd, AMul and AIsEq can be used with Int objects as well. They are useful especially when dealing with arbitrary-precision integers.

Creating

AValue AMakeInt(AThread *t, int i)
Create an std::Int object from a C int value. Raise a direct exception on all error conditions.
AValue AMakeIntU(AThread *t, unsigned i)
Create an std::Int object from a C unsigned value. Raise a direct exception on all error conditions.
AValue AMakeInt64(AThread *t, AInt64 i)
Create an std::Int object from a 64-bit signed integer value. Raise a direct exception on all error conditions.
AValue AMakeIntU64(AThread *t, AIntU64 i)
Create an std::Int object from a 64-bit unsigned integer value. Raise a direct exception on all error conditions.
AValue AMakeInt_size_t(AThread *t, Asize_t i)
Similar to the above functions, but the integer argument type is Asize_t.
AValue AMakeInt_ssize_t(AThread *t, Assize_t i)
Similar to the above functions, but the integer argument type is Assize_t.

Reading

int AGetInt(AThread *t, AValue v)
If v is a Int object in the range of the C int type, return its value as an int. Otherwise, raise a direct std::TypeError or std::ValueError exception.
unsigned AGetIntU(AThread *t, AValue v)
If v is a Int object in the range of the C unsigned type, return its value as an unsigned int. Otherwise, raise a direct std::TypeError or std::ValueError exception.
AInt64 AGetInt64(AThread *t, AValue v)
If v is a Int object in the range of the AInt64 type, return its value as a 64-bit signed integer. Otherwise, raise a direct std::TypeError or std::ValueError exception.
AIntU64 AGetIntU64(AThread *t, AValue v)
If v is a Int object in the range of the AIntU64 type, return its value as a 64-bit unsigned integer. Otherwise, raise a direct std::TypeError or std::ValueError exception.
Asize_t AGetInt_size_t(AThread *t, AValue v)
Similar to the above functions, but the target integer type is Asize_t.
Assize_t AGetInt_ssize_t(AThread *t, AValue v)
Similar to the above functions, but the target integer type is Assize_t.

Checking

ABool AIsInt(AValue v)
Return a boolean indicating whether v is an Int object.
void AExpectInt(AThread *t, AValue v)
Check if v is an Int object and raise a direct std::TypeError exception if it is not.

Arbitrary-precision integers

The previous operations mostly deal with fixed-size integers. Alore integers have an unbounded size, and the functions described below are useful for dealing efficiently with arbitrary-precision integers.

Alore supports two different memory representations of Int objects. A long integer representation must be used for integers that are larger than the constant A_SHORT_INT_MAX or smaller than A_SHORT_INT_MIN. Other integers are always represented using the fixed-size short integer representation.

A long Int object is composed of "digits", fixed-size binary integers, whose range is from 0 to 2**A_LONG_INT_DIGIT_BITS-1. The digits are numbered starting from 0 (the least significant digit) to n-1 (the most significant digit), where n is the length of the long Int object. The most significant digit must always be non-zero.

The magnitude of a long Int object can be calculated using this formula:

value = digit[0] * B**0 + digit[1] * B**1 + ... + digit[n - 1] * B**(n - 1)

Here B is the base or radix (2**A_LONG_INT_DIGIT_BITS). Note that we use ** to mean exponentiation. Negative long Int objects have a sign flag set, so two's complement representation is not used internally to represent negative long integers, although Alore code generally sees integers following two's complement semantics.

Example: If each digit is 16 bits wide, B is 2**16 or 65536, and the value of each digit must be between 0 and 65535. Then consider a negative long Int object with the following digits, starting from digit 0: 5, 4 and 3. The integer value of this object is -5 - 4 * 65536 - 3 * 65536**2 == -12885164037.

API functions that are useful for dealing with long Int objects are described below.

Note: It is an error to create a long Int object if it is in the short Int range, but the API does not enforce this constraint. Therefore you have to be very careful or try to use higher-level operations such as AAdd or AIsLt that work with both short and long forms transparently.

ABool AIsShortInt(AValue v)
Return a boolean indicating whether v is an Int object within the range of a short Int object (i.e. A_SHORT_INT_MIN to A_SHORT_INT_MAX).
ABool AIsLongInt(AValue v)
Return a boolean indicating whether v is an Int object outside the range of a short Int object (i.e. A_SHORT_INT_MIN to A_SHORT_INT_MAX). Note that if v is Int, either AIsShortInt or AIsLongInt is true, but never both.
AValue AMakeLongInt(AThread *t, int len, ABool isNeg)
Create an uninitialized long Int object with len digits (each A_LONG_INT_DIGIT_BITS bits wide), optionally negative. Use ASetLongIntDigit to initialize the contents of the object. After initialization, the most significant digit must not be zero, and the overall value of the object must be outside the short int range. You must fully initialize a long Int object before exposing it to Alore code.
void ASetLongIntDigit(AValue longInt, int num, ALongIntDigit digitValue)
Initialize digit num in a long Int object to the specified value. The long Int object must have been created using AMakeLongInt. The least significant digit is numbered 0. Note that the value argument must refer to a long Int object and num must be in the valid range, since no error checking is performed. After a long Int object has been initialized, its contents must not be modified.
ABool AIsNegLongInt(AValue longInt)
Return a boolean indicating whether a long Int object is negative. Note that the argument must refer to a long Int object, since no error checking is performed.
int ALongIntLen(AValue longInt)
Return the number of digits in a long Int object. Note that the argument must point to a long Int object, since no error checking is performed.
ALongIntDigit AGetLongIntDigit(AValue longInt, int num)
Return the digit num of a long Int object. The least significant digit is numbered 0. Note that the value argument must refer to a long Int object and num must be in the valid range, since no error checking is performed.

Types

ALongIntDigit
An unsigned integral type that is A_LONG_INT_DIGIT_BITS bits wide (16, 32 or 64). It is used to represent a chunk of data, a "digit", in a long integer object.
AShortIntType
A signed integral type that is wide enough to hold all possible short integer values (from A_SHORT_INT_MIN to A_SHORT_INT_MAX). The type is 32 or 64 bits wide.

Constants

A_LONG_INT_DIGIT_BITS
Number of bits in ALongIntDigit. Possible values are 16, 32 and 64.
A_SHORT_INT_MAX
The largest possible value for a short Int object.
A_SHORT_INT_MIN
The smallest possible value for a short Int object.