Integers#
This document describes the Open Dylan implementation of arithmetic functions, especially integer arithmetic. It describes a number of extensions to the Dylan language, which are available from the Dylan library. It also describes a generic arithmetic facility that, through the use of other libraries, allows you to extend arithmetic to special number types, such as “big” (64bit) integers.
Throughout this document, arguments are instances of the class specified
by the argument name (ignoring any numeric suffixes), unless otherwise
noted. Thus, the arguments integer, integer1, and integer2 would
all be instances of the class <integer>
.
The goals of the extensions to the Dylan language described in this document are as follows:
Provide arithmetic operations that are closed over small integers.
This allows type inference to propagate small integer declarations more widely, because there is no possibility of automatic coercion into some more general format.
Make the arithmetic operations that are closed over small integers easily accessible to programmers.
Allow the Dylan library to be described in such a way that only small integers are present by default, moving support for infinite precision integer arithmetic to the BigIntegers library, which must be explicitly used.
Support infinite precision integer arithmetic through the BigIntegers library.
Note
Using that library in another library does not have a negative effect on the correctness or performance of other libraries in the same application that do not use it.
Maintain compatibility with the DRM specification.
In particular, the extensions support the production of efficient code for programs written to be portable with respect to the DRM specification. Use of implementationspecific types or operations in order to get reasonable efficiency is not required. This precludes relegating the
<integer>
class and limited<integer> types to inefficient implementations.Note
When there are several distinct interfaces with the same name but in different modules, the notation interface # module is used in this document to remove ambiguity.
Specify that the class
<integer>
has a finite, implementationdependent range, bounded by the constants$minimuminteger
and$maximuminteger
.The representation for integers must be at least 28 bits, including the sign. That is, the minimum conforming value for
$maximuminteger
is2 ^ 27  1
and the maximum conforming value for$minimuminteger
is2 ^ 27
.Note
Rationale: Restricting
<integer>
in this way allows the programmer to stay in the efficient range without requiring exact knowledge of what that range might be. The full generality of extended precision integers is provided by the BigIntegers library, for programmers who actually need that functionality.Define the type
<machinenumber>
to be the type union of<float>
and<integer>
.
The Dylan library provides implementations of the generic functions and
functions described in this document. If the result of one of these
operations is specified to be an instance of <integer>
and the
mathematically correct result cannot be represented as an <integer>
then an error is signaled. This removes fully generic arithmetic from
the Dylan library. In particular, it removes extended integers, ratios,
and rectangular complex numbers.
Extensions to the dylan Library#
This section describes the extensions to the Dylan library that provide the arithmetic operations available as standard to your applications. You do not have to explicitly use any additional libraries to have access to any of the functionality described in this section. Note that this section only describes extensions to the Dylan library; for complete descriptions, you should also refer to the Dylan Reference Manual.
Note that the CommonDylan library also has these extensions because it uses the Dylan library.
Ranges#
The initialization arguments for <range>
must all be instances of
<machinenumber>
rather than <real>
.
Specific constructors#
The following specific constructors are available for use with the class
<integer>
.
 limited Generic function#
Defines a new type that represents a subset of the class
<integer>
. Signature:
limited integerclass #key min max => limitedtype
 Parameters:
integerclass – The singleton(<integer>).
min – The lower bound of the range. The default is
$minimuminteger
.max – The upper bound of the range. The default is
$maximuminteger
.
 Discussion:
The integerclass argument is the class
<integer>
, and all other arguments are instances of<integer>
. The range of<integer>
is bounded by default.
 range Function#
This function is used to specify ranges of numbers.
 Signature:
range (#key from:, to:, above:, below:, by:, size:) => <range>
 Discussion:
All of the supplied arguments must be instances of
<machinenumber>
.
Equality comparisons#
The =
function compares two objects and returns #t
if the values of
the two objects are equal to each other, that is of the same magnitude.
 = Open Generic function#
 Signature:
= object1 object2 => boolean
 Discussion:
Tests its arguments to see if they are of the same magnitude.
 =(<complex>) Sealed Method#
Tests its arguments to see if they are of the same magnitude.
 Signature:
= complex1 complex2 => boolean
 =(<machinenumber>) Method#
Tests its arguments to see if they are of the same magnitude.
 Signature:
= machinenumber1 machinenumber2 => boolean
Magnitude comparisons#
The Dylan library provides the following interfaces for testing the magnitude of two numbers:
 < Open Generic function#
Returns
#t
if its first argument is less than its second argument. Signature:
< object1 object2 => boolean
Properties of numbers#
Various number properties can be tested using the following predicates in the Dylan library:
 odd? Open Generic function#
Tests whether the argument supplied represents an odd value.
 Signature:
odd? object => boolean
 odd?(<complex>) Sealed Method#
 Signature:
odd? complex => boolean
 Discussion:
Tests whether the argument supplied represents an odd value.
 odd?(<integer>) Method#
Tests whether the argument supplied represents an odd value.
 Signature:
odd? integer => boolean
 even? Open Generic function#
Tests whether the argument supplied represents an even value
 Signature:
even? object => boolean
 even?(<complex>) Sealed Method#
Tests whether the argument supplied represents an even value
 Signature:
even? complex => boolean
 even?(<integer>) Method#
Tests whether the argument supplied represents an even value
 Signature:
even? integer => boolean
 zero? Open Generic function#
Tests whether the argument supplied represents a zero value.
 Signature:
zero? object => boolean
 zero?(<complex>) Sealed Method#
Tests whether the argument supplied represents a zero value.
 Signature:
zero? complex => boolean
 zero?(<machinenumber>) Method#
Tests whether the argument supplied represents a zero value.
 Signature:
zero? machinenumber => boolean
 positive? Open Generic function#
Tests whether the argument supplied represents a positive value.
 positive?(<complex>) Sealed Method#
 Signature:
positive? complex
 Discussion:
Tests whether the argument supplied represents a positive value.
 positive?(<machinenumber>) Method#
 Signature:
positive? machinenumber => boolean
 Discussion:
Tests whether the argument supplied represents a positive value.
 negative? Open Generic function#
Tests whether the argument supplied represents a negative value.
 Signature:
negative? object => boolean
 negative?(<complex>) Sealed Method#
Tests whether the argument supplied represents a negative value.
 Signature:
negative? complex => boolean
 negative?(<machinenumber>) Method#
Tests whether the argument supplied represents a negative value.
 Signature:
negative? machinenumber => boolean
 integral? Open Generic function#
Tests whether the argument supplied represents an integral value.
 Signature:
integral? object => boolean
 integral?(<complex>) Sealed Method#
Tests whether the argument supplied represents an integral value.
 Signature:
integral? complex
 integral?(<machinenumber>) Method#
Tests whether the argument supplied represents an integral value.
 Signature:
integral? machinenumber => boolean
Arithmetic operations#
The following arithmetic operations are available in the Dylan library:
 + Open Generic function#
Returns the sum of the two supplied arguments. The actual type of the value is determined by the contagion rules when applied to the arguments.
 Signature:
object1 object2 => #rest object
 +(<complex>, <complex>) Sealed Method#
 Signature:
complex1 complex2
 +(<integer>, <complex>) Method#
 Signature:
integer1 integer2 => integer
 +(<machinenumber>, <machinenumber>) Method#
 Signature:
machinenumber1 machinenumber2 => machinenumber
  Open Generic function#
Returns the result of subtracting the second argument from the first. The actual type of the value is determined by the contagion rules when applied to the arguments.
 Signature:
object1 object2 => #rest object
 (<complex>, <complex>) Sealed Method#
 Signature:
complex1 complex2
 (<integer>, <integer>) Method#
 Signature:
integer1 integer2 => integer
 (<machinenumber>, <machinenumber>) Method#
 Signature:
machinenumber1 machinenumber2 => machinenumber
 * Open Generic function#
Returns the result of multiplying the two arguments. The actual type of the value is determined by the contagion rules when applied to the arguments.
 Signature:
object1 object2 => #rest object
 *(<complex>, <complex>) Sealed Method#
 Signature:
* complex1 complex2
 *(<integer>, <integer>) Method#
 Signature:
* integer1 integer2 => integer
 *(<machinenumber>, <machinenumber>) Method#
 Signature:
* machinenumber1 machinenumber2 => machinenumber
 / Open Generic function#
Returns the result of dividing the first argument by the second. The actual type of the value is determined by the contagion rules when applied to the arguments.
 Signature:
/ object1 object2 => #rest object
 /(<complex>, <complex>) Sealed Method#
 Signature:
/ complex1 complex2
 /(<float>, <float>) Method#
 Signature:
/ float1 float2 => float
 negative Open Generic function#
Negates the supplied argument. The returned value is of the same float format as the supplied argument.
 Signature:
negative object => #rest negativeobject
 negative(<complex>) Sealed Method#
 Signature:
negative complex
 negative(<integer>) Method#
 Signature:
negative integer => negativeinteger
 negative(<float>) Method#
 Signature:
negative float => negativefloat
 floor Generic function#
Truncates a number toward negative infinity. The integer part is returned as integer, the remainder is of the same float format as the argument.
 Signature:
floor object => integer object
 floor(<machinenumber>) Method#
 Signature:
floor machinenumber => integer machinenumber
 floor(<integer>) Method#
 Signature:
floor integer => integer integer
 floor(<float>) Method#
 Signature:
floor float => integer float
 ceiling Generic function#
Truncates a number toward positive infinity. The integer part is returned as integer, the remainder is of the same float format as the argument.
 Signature:
ceiling machinenumber => integer machinenumber
 ceiling(<machinenumber>) Method#
 Signature:
ceiling machinenumber => integer machinenumber
 ceiling(<integer>) Method#
 Signature:
ceiling integer => integer integer
 ceiling(<float>) Method#
 Signature:
ceiling float => integer float
 round Generic function#
Rounds a number toward the nearest mathematical integer. The integer part is returned as integer, the remainder is of the same float format as the argument. If the argument is exactly between two integers, then the result integer will be a multiple of two.
 Signature:
round object => integer object
 round(<machinenumber>) Method#
 Signature:
round machinenumber => integer machinenumber
 round(<integer>) Method#
 Signature:
round integer => integer integer
 round(<float>) Method#
 Signature:
round float => integer float
 truncate Generic function#
Truncates a number toward zero. The integer part is returned as integer, the remainder is of the same float format as the argument.
 Signature:
truncate machinenumber => integer object
 truncate(<machinenumber>) Method#
 Signature:
truncate machinenumber => integer machinenumber
 truncate(<integer>) Method#
 Signature:
truncate integer => integer integer
 truncate(<float>) Method#
 Signature:
truncate float => integer float
 floor/ Generic function#
Divides the first argument into the second and truncates the result toward negative infinity. The integer part is returned as integer, the type of the remainder is determined by the contagion rules when applied to the arguments.
 Signature:
floor/ object1 object2 => integer machinenumber
 floor/(<machinenumber>, <machinenumber>) Method#
 Signature:
floor/ machinenumber1 machinenumber2 => integer machinenumber
 floor/(<integer>, <integer>) Method#
 Signature:
floor/ integer1 integer2 => integer integer
 ceiling/ Generic function#
Divides the first argument into the second and truncates the result toward positive infinity. The integer part is returned as integer, the type of the remainder is determined by the contagion rules when applied to the arguments.
 Signature:
ceiling/ object1 object2 => integer object
 ceiling/(<machinenumber>, <machinenumber>) Method#
 Signature:
ceiling/ machinenumber1 machinenumber2 => integer machinenumber
 ceiling/(<integer>, <integer>) Method#
 Signature:
ceiling/ integer1 integer2 => integer integer
 round/ Generic function#
Divides the first argument into the second and rounds the result toward the nearest mathematical integer. The integer part is returned as integer, the type of the remainder is determined by the contagion rules when applied to the arguments.
 Signature:
round/ object1 object2 => integer machinenumber
 round/(<machinenumber>, <machinenumber>) Method#
 Signature:
round/ machinenumber1 machinenumber2 => integer machinenumber
 round/(<integer>, <integer>) Method#
 Signature:
round/ integer1 integer2 => integer integer
 truncate/ Generic function#
Divides the first argument into the second and truncates the result toward zero. The integer part is returned as integer, the type of the remainder is determined by the contagion rules when applied to the arguments.
 Signature:
truncate/ machinenumber1 machinenumber2 => integer machinenumber
 truncate/(<integer>, <integer>) Method#
 Signature:
truncate/ integer1 integer2 => integer integer
 modulo Generic function#
Returns the second value of floor/ ( arg1 , arg2 ). The actual type of the second value is determined by the contagion rules when applied to the arguments.
 Signature:
modulo machinenumber1 machinenumber2 => machinenumber
 modulo(<machinenumber>, <machinenumber>) Method#
 Signature:
modulo machinenumber1 machinenumber2 => machinenumber
 modulo(<integer>, <integer>) Method#
 Signature:
modulo integer1 integer2 => integer
 remainder Generic function#
Returns the second value of
truncate/
(* arg1 , arg2 ).The actual type of the second value is determined by the contagion rules when applied to the arguments. Signature:
remainder machinenumber1 machinenumber2 => machinenumber
 remainder(<integer>, <integer>) Method#
 Signature:
remainder integer1 integer2 => integer
 ^ Open Generic function#
Returns the first argument raised to the power of the second argument. The value is of the same float format as the first argument. An error is signalled if both arguments are 0.
 Signature:
^ object1 object2 => #rest object
 ^(<complex>, <complex>) Sealed Method#
 Signature:
^ complex1 complex2
 ^(<integer>, <integer>) Method#
 Signature:
^ integer1 integer2 => integer
 ^(<float>, <integer>) Method#
 Signature:
^ float1 integer2 => float
 abs Open Generic function#
Returns the absolute value of the argument. The value is of the same float format as the argument.
 Signature:
abs object => #rest object
 abs(<complex>) Sealed Method#
 Signature:
abs complex
 abs(<integer>) Method#
 Signature:
abs integer => integer
 abs(<float>) Method#
 Signature:
abs float => float
 logior Function#
Returns the bitwise inclusive OR of its integer arguments.
 Signature:
logior #rest integers => integer
 logxor Function#
Returns the bitwise exclusive OR of its integer arguments.
 Signature:
logxor #rest integers => integer
 logand Function#
Returns the bitwise AND of its integer arguments.
 Signature:
logand #rest integers => integer
 lognot Function#
Returns the bitwise NOT of its integer arguments.
 Signature:
lognot integer1 => integer2
 logbit? Function#
Tests the value of a particular bit in its integer argument. The index argument is an instance of
<integer>
. Signature:
logbit? index integer => boolean
 ash Function#
Performs an arithmetic shift on its first argument.
 Signature:
ash integer1 count => integer
 lcm Function#
Returns the least common multiple of its two arguments.
 Signature:
lcm integer1 integer2 => integer
 gcd Function#
Returns the greatest common divisor of its two arguments.
 Signature:
gcd integer1 integer2 => integer
Collections#
The keys for sequences are always instances of <integer>
. This means
that certain kinds of collections cannot be sequences; very large (or
unbounded) sparse arrays are an example.
The Table Protocol#
See Language Differences for a list of changes to the table protocol.
Iteration Constructs#
 for Statement Macro#
The start, bound, and increment expressions in a numeric clause must evaluate to instances of
<machinenumber>
for this macro.
The genericarithmetic Library#
The GenericArithmetic library exports the functions described in this section from a module called genericarithmetic.
The GenericArithmetic library provides a fully extensible version of all arithmetic operations. If an application only uses GenericArithmetic, these versions of the operators reduce themselves to be equivalent to those in the Dylan library. But when you use additional implementation libraries, the arithmetic operators are extended.
The BigIntegers library is one such implementation library. It provides a
implementation of <integer>
that uses two machine words to represent
each integer. For example, on a 64bit machine architecture this is a 128bit
signed integer.
The standard integer implementation in the Dylan library is actually part of the following class hierarchy:
<abstractinteger>
├── <integer>
└── <biginteger>
└── <doubleinteger>
(The classes <biginteger>
and <doubleinteger>
are implementation
classes. You do not need to use them.)
The modules in the GenericArithmetic library export <abstractinteger>
with the name <integer>
. They also export a full set of arithmetic
operators that use instances of <abstractinteger>
rather than instances
of <integer>
(in the Dylan library naming scheme). However, those
operators just fall back to the Dylan library operators until you include an
implementation library, such as BigIntegers, in your application.
When you use the BigIntegers library, the arithmetic operators exported by
GenericArithmetic are enhanced to extend their results to 128bit integers on
64bit machines or 64bit integers on 32bit machine architectures. If a result
is small enough to fit in a Dylan library <integer>
, it will be fitted
into one.
Note that the GenericArithmetic library uses the same naming conventions for arithmetic operators as used by the Dylan library. This means that some renaming is required in modules that require access to both the basic Dylan interfaces and the interfaces supplied by the GenericArithmetic library. As described earlier, the notation interface # module is used to denote different interfaces of the same name, where interface is the name of the interface, and module is the name of the module it is exported from.
See Using special arithmetic features for an example of how to use an implementation library with GenericArithmetic.
Ranges#
The GenericArithmetic library defines the class <range>
, which is in
most respects functionally equivalent to <range>#Dylan, but uses generic
arithmetic operations in its implementation so that the initialization
arguments can be instances of <real>
, rather than being restricted to
<machinenumber>
.
Classes#
The class <abstractinteger>
is imported and reexported under the
name <integer>#genericarithmetic.
Specific constructors#
 range Function
 Signature:
range #key from to above below by size => range
This function is identical to the function range#Dylan, except that
all of the supplied arguments must be instances of <real>
.
Arithmetic operations#
The following functions all have GenericArithmetic implementations that are
mathematically equivalent to the corresponding implementations defined on
<integer>
and documented in the DRM. See Arithmetic operations
for descriptions of each function as
implemented in the Dylan library.
+
object1 object2 => #rest object

object1 object2 => #rest object
*
object1 object2 => #rest object
/
object1 object2 => #rest object
negative
object => #rest negativeobject
floor
real1 => abstractinteger real
ceiling
real1 => abstractinteger real
round
real1 => abstractinteger real
truncate
real1 => abstractinteger real
floor/
real1 real2 => abstractinteger real
ceiling/
real1 real2 => abstractinteger real
round/
real1 real2 => abstractinteger real
truncate/
real1 real2 => abstractinteger real
modulo
real1 real2 => real
remainder
real1 real2 => real
^
object1 object2 => #rest object
abs
object1 => #rest object
logior
#rest abstractinteger1 => abstractinteger
logxor
#rest abstractinteger1 => abstractinteger
logand
#rest abstractinteger1 => abstractinteger
lognot
abstractinteger1 => abstractinteger
logbit?
integer abstractinteger => boolean
ash
abstractinteger1 integer => abstractinteger
lcm
abstractinteger1 abstractinteger2 => abstractinteger
gcd
abstractinteger1 abstractinteger2 => abstractinteger
Iteration constructs#
While a programmer could make use of generic arithmetic in a for
loop
by using explicitstep clauses, this approach leads to a loss of
clarity. The definition of the for
macro is complex, so a version that
uses generic arithmetic in numeric clauses is provided, rather than
requiring programmers who want that feature to reconstruct it.
 for Statement Macro
The start, bound, and increment expressions in a numeric clause must evaluate to instances of
<machinenumber>
for this macro. Otherwise, this macro is similar to for#Dylan.
Exported Modules from the genericarithmetic Library#
The GenericArithmetic library exports several modules that are provided for the convenience of programmers who wish to create additional modules based on the dylan module plus various combinations of the arithmetic models.
The dylanexcludingarithmetic Module#
The DylanExcludingArithmetic module imports and reexports all of the interfaces exported by the dylan module from the Dylan library, except for the following excluded interfaces:
The dylanarithmetic Module#
The DylanArithmetic module imports and reexports all of the interfaces exported by the dylan module from the Dylan library which are excluded by the dylanexcludingarithmetic module.
The genericarithmeticdylan Module#
The GenericArithmeticDylan module imports and reexports all of the interfaces exported by the dylanexcludingarithmetic module and the genericarithmetic module.
The dylanexcludingarithmetic, dylanarithmetic, and genericarithmetic modules provide convenient building blocks for programmers to build the particular set of global name bindings they wish to work with. The purpose of the genericarithmeticdylan module is to provide a standard environment in which generic arithmetic is the norm, for those programmers who might want that.
Using Special Arithmetic Features#
As noted in The GenericArithmetic library, the GenericArithmetic library provides an extensible protocol for adding specialized arithmetic functionality to your applications. By using the GenericArithmetic library alongside a special implementation library, you can make the standard arithmetic operations support number types such as big (128bit or 64bit) integers, or complex numbers.
This section provides an example of extending the basic Dylan arithmetic features using the GenericArithmetic library and the BigIntegers implementation library.
To use special arithmetic features, a library’s define library
declaration must use at least the following libraries:
commondylan
genericarithmetic
specialarithmeticimplementationlibrary
So for BigIntegers you would write:
define library foo
use commondylan;
use genericarithmetic;
use bigintegers;
...
end library foo;
Next you have to declare a module. There are three ways of using biginteger arithmetic that we can arrange with a suitable module declaration:
Replace all integer arithmetic with the biginteger arithmetic.
Use both, with normal arithmetic remaining the default.
Use both, with the biginteger arithmetic becoming the default.
To get one of the three different effects described above, you need to
arrange the define module
declaration accordingly. To replace all
integer arithmetic with biginteger arithmetic, include the following in
your define module
declaration:
use genericarithmeticcommondylan;
(Note that the module definition should not use the BigIntegers module. The BigIntegers library is used as a sideeffects library only, that is, it is referenced in the library definition so that it will be loaded. Its definitions extend the GenericArithmetic library.)
If you replace all integer arithmetic with biginteger arithmetic in this way, there will be performance hits. For instance, loop indices will have to be checked at runtime to see whether a normal or big integer representation is being used, and a choice must be made about the representation for an incremented value.
You can take a different approach that reduces the cost of biginteger
arithmetic. Under this approach you leave normal integer arithmetic
unchanged, and get access to biginteger arithmetic when you need it. To
do this, use the same libraries but instead of using the
commondylangenericarithmetic
module, include the following in your
define module
declaration:
use commondylan;
use genericarithmetic, prefix: "generic/"; // use any prefix you like
This imports the biginteger arithmetic binding names, but gives them a prefix
generic/
, using the standard renaming mechanism available in module
declarations. Thus you gain access to big arithmetic using renamed classes and
operations like:
generic/<integer>
generic/+
generic/
generic/*
...
The operations take either instances of <integer>
or
generic/<integer>
(a subclass of <integer>
) and return instances of
generic/<integer>
.
Note that having imported the biginteger operations under new names, you have to use prefix rather than infix syntax when calling them. For example:
generic/+(5, 4);
not:
5 generic/+ 4;
The existing functions like +
and 
will only accept <integer>
instances and generic/<integer>
instances small enough to be represented as
<integer>
instances.
Under this renaming scheme, reduced performance will be confined to the
generic/
operations. Other operations, such as loop index increments and
decrements, will retain their efficiency.
Finally, you can make biginteger arithmetic the default but keep normal
arithmetic around for when you need it. Your define module
declaration should contain:
use genericarithmeticcommondylan;
use dylanarithmetic, prefix: "dylan/"; //use any prefix you like
The bigintegers Library#
The BigIntegers library exports a module called bigintegers
, which
imports and reexports all of the interfaces exported by the
genericarithmetic
module of the GenericArithmetic library.
The BigIntegers library modifies the behavior of functions provided by the Dylan library as described in this section.
Specific Constructors#
The BigIntegers library extends the functionality of specific constructors in the Dylan library as follows:
 limited Function
 Signature:
limited abstractintegerclass #key min max => limitedtype
Returns a limited integer type, which is a subtype of
<abstractinteger>
, whose instances are integers greater than or
equal to min (if specified) and less than or equal to max (if
specified). If no keyword arguments are specified, the result type is
equivalent to <abstractinteger>
. The argument
abstractintegerclass is the class <abstractinteger>
.
If both min and max are supplied, and both are instances of
<integer>
, then the result type is equivalent to calling limited on
<integer>
with those same bounds.
The Limited Integer Type Protocol is extended to account for limited
<abstractinteger>
types.
Instances and subtypes in the BigIntegers library#
In each of the following code snippets, the expression in the first line is true if and only if all of the expressions following it are true.
instance?(x, limited(<abstractinteger>, min: y, max: z))
instance?(x, <abstractinteger>)
y <= x
x <= z
instance?(x, limited(<abstractinteger>, min: y))
instance?(x, <abstractinteger>)
y <= x
instance?(x, limited(<abstractinteger>, max: z))
instance?(x, <abstractinteger>)
x <= z
subtype?(limited(<abstractinteger>, min: w, max: x),
limited(<abstractinteger>, min: y, max: z))
w >= y
x <= z
subtype?(limited(<abstractinteger>, min: w ...),
limited(<abstractinteger>, min: y))
w >= y
subtype?(limited(<abstractinteger>, max: x ...),
limited(<abstractinteger>, max: z))
x <= z
Typeequivalence in the BigIntegers library#
In each of the following code snippets, the expression on the first line is type equivalent to the expression on the second line if and only if the text following both expressions is true.
limited(<abstractinteger>, min: y, max: z)
limited(<integer>, min: y, max: z)
y and z are both instances of <integer>
.
limited(<abstractinteger>, min: y, max: $maximuminteger)
limited(<integer>, min: y)
y is an instance of <integer>
.
limited(<abstractinteger>, min: $minimuminteger, max: z)
limited(<integer>, max: z)
z is an instance of <integer>
.
Type disjointness is modified as follows to account for limited
<abstractinteger>
types.
A limited integer type is disjoint from a class if their base types are
disjoint or the class is <integer>
and the range of the limited
integer type is disjoint from the range of <integer>
(that is, from
$minimuminteger to $maximuminteger).
Equality comparisons#
The behavior of equality comparisons in the Dylan library is modified by the BigIntegers library as follows:
= *abstractinteger1* *abstractinteger2* => *boolean*
= *abstractinteger* *float* => *boolean*
= *float* *abstractinteger* => *boolean*
Magnitude comparisons#
The behavior of magnitude comparisons in the Dylan library is modified by the BigIntegers library as follows:
< *abstractinteger1* *abstractinteger2* => *boolean
< *abstractinteger* *float* => *boolean*
< *float* *abstractinteger* => *boolean*
Properties of Numbers#
The behavior of number property tests in the Dylan library is modified by the BigIntegers library as follows:
odd? *abstractinteger* => *boolean*
even? *abstractinteger* => *boolean*
zero? *abstractinteger* => *boolean*
positive? *abstractinteger* => *boolean*
negative? *abstractinteger* => *boolean*
integral? *abstractinteger* => *boolean*
Arithmetic Operations#
The BigIntegers library modifies the behavior of the functions provided by the GenericArithmetic library as described below.
The actual type of the return value for all the following interfaces is determined by the contagion rules when applied to the arguments.
+ *abstractinteger1* *abstractinteger2* => *abstractinteger*
+ *abstractinteger* *float1* => *float*
+ *float1* *abstractinteger* => *float*
 *abstractinteger1* *abstractinteger2* => *abstractinteger*
 *abstractinteger* *float1* => *float*
 *float1* *abstractinteger* => *float*
* *abstractinteger1* *abstractinteger2* => *abstractinteger*
* *abstractinteger* *float1* => *float*
* *float1* *abstractinteger* => *float*
The return value of the following interface is of the same float format as the argument:
negative *abstractinteger* => *negativeabstractinteger*
The second return value of all the following interfaces is of the same float format as the argument:
floor *abstractinteger* => *abstractinteger1* *abstractinteger2*
floor *float1* => *abstractinteger* *float*
ceiling *abstractinteger* => *abstractinteger1* *abstractinteger2*
ceiling *float1* => *abstractinteger* *float*
round *abstractinteger* => *abstractinteger1* *abstractinteger2*
round *float1* => *abstractinteger* *float*
truncate *abstractinteger* => *abstractinteger1* *abstractinteger2*
truncate *float1* => *abstractinteger* *float*
The second return value of all the following interfaces is of the same float format as the first argument:
floor/ *abstractinteger1* *abstractinteger2* => *abstractinteger3* *abstractinteger4*
floor/ *float1* *abstractinteger1* => *abstractinteger2* *float2*
ceiling/ *abstractinteger1* *abstractinteger2* => *abstractinteger3* *abstractinteger4*
ceiling/ *float1* *abstractinteger1* => *abstractinteger2* *float2*
round/ *abstractinteger1* *abstractinteger2* => *abstractinteger3* *abstractinteger4*
round/ *float1* *abstractinteger1* => *abstractinteger2* *float2*
truncate/ *abstractinteger1* *abstractinteger2* => *abstractinteger3* *abstractinteger4
truncate/ *float1* *abstractinteger1* => *abstractinteger2* *float2*
The second return value of the following interfaces is of the same float format as the second argument:
floor/ *abstractinteger1* *float1* => *abstractinteger2* *float2*
ceiling/ *abstractinteger1* *float1* => *abstractinteger2* *float2*
round/ *abstractinteger1* *float1* => *abstractinteger2* *float2*
truncate/ *abstractinteger1* *float1* => *abstractinteger2* *float2*
The return value of the following interfaces is of the same float format as the first argument:
modulo *float1* *abstractinteger* => *float*
remainder *float1* *abstractinteger* => *float*
The return value of the following interfaces is of the same float format as the second argument:
modulo *abstractinteger1* *abstractinteger2* => *abstractinteger*
modulo *abstractinteger* *float1* => *float*
remainder *abstractinteger1* *abstractinteger2* => *abstractinteger*
remainder *abstractinteger* *float1* => *float*
The behavior of the following miscellaneous interfaces is also modified by the BigIntegers library:
^ *abstractinteger1* *integer* => *abstractinteger
abs *abstractinteger1* => *abstractinteger*
logior #rest *abstractinteger1* => *abstractinteger*
logxor #rest *abstractinteger1* => *abstractinteger*
logand #rest *abstractinteger1* => *abstractinteger*
lognot *abstractinteger1* => *abstractinteger*
logbit? *integer* *abstractinteger* => *boolean*
ash *abstractinteger1* *integer* => *abstractinteger*
lcm *abstractinteger1* *abstractinteger2* => *abstractinteger*
gcd *abstractinteger1* *abstractinteger2* => *abstractinteger*