%--------------------------------------------------% % vim: ts=4 sw=4 et ft=mercury %--------------------------------------------------% % Copyright (C) 1997-2000, 2003-2007, 2011-2012 The University of Melbourne. % Copyright (C) 2014-2022 The Mercury team. % This file is distributed under the terms specified in COPYING.LIB. %--------------------------------------------------% % % File: integer.m. % Main authors: aet, Dan Hazel <odin@svrc.uq.edu.au>. % Stability: high. % % This module defines an arbitrary precision integer type (named "integer") % and basic arithmetic operations on it. % % The builtin Mercury type "int" is implemented as machine integers, % which on virtually all modern machines will be 32 or 64 bits in size. % If you need to manipulate integers that may not fit into this many bits, % you will want to use "integer"s instead of "int"s. % % NOTE: All the operators we define on "integers" behave the same as the % corresponding operators on "int"s. This includes the operators related % to division: /, //, rem, div, and mod. % %--------------------------------------------------% %--------------------------------------------------% :- module integer. :- interface. :- type integer. %--------------------------------------------------% % % Constants. % % Equivalent to integer(-1). % :- func negative_one = integer. % Equivalent to integer(0). % :- func zero = integer. % Equivalent to integer(1). % :- func one = integer. % Equivalent to integer(2). % :- func two = integer. % Equivalent to integer(8). % :- func eight = integer. % Equivalent to integer(10). % :- func ten = integer. % Equivalent to integer(16). % :- func sixteen = integer. %--------------------------------------------------% % X < Y: Succeed if and only if X is less than Y. % :- pred '<'(integer::in, integer::in) is semidet. % X > Y: Succeed if and only if X is greater than Y. % :- pred '>'(integer::in, integer::in) is semidet. % X =< Y: Succeed if and only if X is less than or equal to Y. % :- pred '=<'(integer::in, integer::in) is semidet. % X >= Y: Succeed if and only if X is greater than or equal to Y. % :- pred '>='(integer::in, integer::in) is semidet. % Absolute value. % :- func abs(integer) = integer. % True if the argument is equal to integer.zero. % :- pred is_zero(integer::in) is semidet. %--------------------------------------------------% % Unary plus. % :- func '+'(integer) = integer. % Unary minus. % :- func '-'(integer) = integer. % Addition. % :- func integer + integer = integer. % Subtraction. % :- func integer - integer = integer. % Multiplication. % :- func integer * integer = integer. % Flooring integer division. % Behaves as int.div. % :- func integer div integer = integer. % Truncating integer division. % Behaves as int.(//). % :- func integer // integer = integer. % Modulus. % Behaves as int.mod. % :- func integer mod integer = integer. % Remainder. % Behaves as int.rem. % :- func integer rem integer = integer. % divide_with_rem(X, Y, Q, R) where Q = X // Y and R = X rem Y % where both answers are calculated at the same time. % :- pred divide_with_rem(integer::in, integer::in, integer::out, integer::out) is det. % Exponentiation. % pow(X, Y) = Z: Z is X raised to the Yth power. % Throws a `domain_error' exception if Y is negative. % :- func pow(integer, integer) = integer. %--------------------------------------------------% % Left shift. % Behaves as int.(<<). % :- func integer << int = integer. % Right shift. % Behaves as int.(>>). % :- func integer >> int = integer. %--------------------------------------------------% % Bitwise complement. % :- func \ integer = integer. % Bitwise and. % :- func integer /\ integer = integer. % Bitwise or. % :- func integer \/ integer = integer. % Bitwise exclusive or (xor). % :- func integer `xor` integer = integer. %--------------------------------------------------% % Convert an integer to an int. % Fails if the integer is not in the range [min_int, max_int]. % :- pred to_int(integer::in, int::out) is semidet. % As above, but throws an exception rather than failing. % :- func det_to_int(integer) = int. %--------------------------------------------------% % Convert an integer to a uint. % Fails if the integer is not in the range [0, max_uint]. % :- pred to_uint(integer::in, uint::out) is semidet. % As above, but throws an exception rather than failing. % :- func det_to_uint(integer) = uint. % Convert an integer to an int8. % Fails if the integer is not in the range [-128, 127]. % :- pred to_int8(integer::in, int8::out) is semidet. % As above, but throws an exception rather than failing. % :- func det_to_int8(integer) = int8. % Convert an integer to a uint8. % Fails if the integer is not in the range [0, 255]. % :- pred to_uint8(integer::in, uint8::out) is semidet. % As above, but throws an exception rather than failing. % :- func det_to_uint8(integer) = uint8. % Convert an integer to an int16. % Fails if the integer is not in the range [-32768, 32767]. % :- pred to_int16(integer::in, int16::out) is semidet. % As above, but throws an exception rather than failing. % :- func det_to_int16(integer) = int16. % Convert an integer to a uint16. % Fails if the integer is not in the range [0, 65535]. % :- pred to_uint16(integer::in, uint16::out) is semidet. % As above, but throws an exception rather than failing. % :- func det_to_uint16(integer) = uint16. % Convert an integer to an int32. % Fails if the integer is not in the range [-2147483648, 2147483647]. % :- pred to_int32(integer::in, int32::out) is semidet. % As above, but throws an exception rather than failing. % :- func det_to_int32(integer) = int32. % Convert an integer to a uint32. % Fails if the integer is not in range [0, 4294967295]. % :- pred to_uint32(integer::in, uint32::out) is semidet. % As above, but throws an exception rather than failing. % :- func det_to_uint32(integer) = uint32. % Convert an integer to an int64. % Fails if the integer is not in the range % [-9223372036854775808, 9223372036854775807]. % :- pred to_int64(integer::in, int64::out) is semidet. % As above, but throws an exception rather than failing. % :- func det_to_int64(integer) = int64. % Convert an integer to a uint64. % Fails if the integer is not in range [0, 18446744073709551615]. % :- pred to_uint64(integer::in, uint64::out) is semidet. % As above, but throws an exception rather than failing. % :- func det_to_uint64(integer) = uint64. %--------------------------------------------------% % Convert an integer to a float. % :- func float(integer) = float. %--------------------------------------------------% % Convert an integer to a string (in base 10). % :- func to_string(integer) = string. % to_base_string(Integer, Base) = String: % % Convert an integer to a string in a given Base. % % Base must be between 2 and 36, both inclusive; if it is not, % the predicate will throw an exception. % :- func to_base_string(integer, int) = string. %--------------------------------------------------% % Convert an int to integer. % :- func integer(int) = integer. % Convert a uint to an integer. % :- func from_uint(uint) = integer. % Convert an int8 to an integer. % :- func from_int8(int8) = integer. % Convert a uint8 to an integer. % :- func from_uint8(uint8) = integer. % Convert an int16 to an integer. % :- func from_int16(int16) = integer. % Convert a uint16 to an integer. % :- func from_uint16(uint16) = integer. % Convert an int32 to an integer. % :- func from_int32(int32) = integer. % Convert a uint32 to an integer. % :- func from_uint32(uint32) = integer. % Convert an int64 to an integer. % :- func from_int64(int64) = integer. % Convert a uint64 to an integer. % :- func from_uint64(uint64) = integer. % Convert a string to an integer. The string must contain only digits % [0-9], optionally preceded by a plus or minus sign. If the string does % not match this syntax, then the predicate fails. % :- pred from_string(string::in, integer::out) is semidet. % As above, but throws an exception rather than failing. % :- func det_from_string(string) = integer. % Convert a string in the specified base (2-36) to an integer. % The string must contain one or more digits in the specified base, % optionally preceded by a plus or minus sign. For bases > 10, digits % 10 to 35 are represented by the letters A-Z or a-z. If the string % does not match this syntax, then the predicate fails. % :- pred from_base_string(int::in, string::in, integer::out) is semidet. % As above, but throws an exception rather than failing. % :- func det_from_base_string(int, string) = integer. %--------------------------------------------------% %--------------------------------------------------%