dwayne/elm-integer/1.0.0

Integer

Compute with the integers, ℤ = { ..., -2, -1, 0, 1, 2, ... }.

Representation

type Integer

A representation of the integers.

If you must know, it uses a sign-magnitude representation.

N.B. The size of the numbers you can compute with is only limited by the available memory.

Constants

The integers from -10 to 10 inclusive are named.

The integer 0.

To be more precise, it is a representation of the integer 0. However, I will not have any cause to make that distinction. A similar remark can be made about the other constants.

The integer 1.

The integer 2.

The integer 3.

The integer 4.

The integer 5.

The integer 6.

The integer 7.

The integer 8.

The integer 9.

The integer 10.

The integer -1.

The integer -2.

The integer -3.

The integer -4.

The integer -5.

The integer -6.

The integer -7.

The integer -8.

The integer -9.

The integer -10.

Limits

Let n : Int. If minSafeInt <= n <= maxSafeInt then n is called a safe Int.

The largest Int, currently 2^53 - 1 = 9007199254740991, which can be given as input to fromSafeInt and fromInt without causing problems.

The smallest Int, currently -2^53 + 1 = -9007199254740991, which can be given as input to fromSafeInt and fromInt without causing problems.

Constructors

Use this function when you know the given Int is a safe Int.

fromSafeInt 0 == zero


fromSafeInt 1 == one


fromSafeInt -1 == negativeOne


fromSafeInt maxSafeInt == fromSafeString "9007199254740991"


fromSafeInt minSafeInt == fromSafeString "-9007199254740991"

If the given Int isn't safe then zero is returned.

fromSafeInt (minSafeInt - 1) == zero


fromSafeInt (maxSafeInt + 1) == zero

This function is useful for establishing small constants in a calculation. For e.g. to compute the first 100 digits of π using John Machin's formula the integer 239 is needed.

twoThirtyNine : Integer
twoThirtyNine =
    fromSafeInt 239
fromInt : Int -> Maybe Integer

Create the integer that represents the given Int.

fromInt 0 == Just zero


fromInt 1 == Just one


fromInt -1 == Just negativeOne


fromInt maxSafeInt == fromString "9007199254740991"


fromInt minSafeInt == fromString "-9007199254740991"

Unless the given Int is less than minSafeInt or greater than maxSafeInt.

fromInt (minSafeInt - 1) == Nothing


fromInt (maxSafeInt + 1) == Nothing
fromNatural : Natural -> Integer

If you happen to have a natural number at hand then you can convert it to an integer using this function.

For all n : Natural:

  • toNatural (fromNatural n) == n,
  • isNonNegative (fromNatural n) == True.

It's best to use this function when you can guarantee that the string you're dealing with is a valid input to the fromString function.

If the input is invalid then zero is returned.

N.B. Read the documentation of fromString to learn what's considered to be valid or invalid input to this function.

This function is useful for establishing large constants in a calculation.

oneGoogol : Natural
oneGoogol =
    -- 10 ^ 100
    fromSafeString "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"

Learn more about a googol.

What's considered a large constant?

Let n : Int, since fromSafeInt n can be used for minSafeInt <= n <= maxSafeInt then it makes sense to consider any integer smaller than minSafeInt or larger than maxSafeInt, a large constant.

fromString : String -> Maybe Integer

Create the integer represented by the given signed string.

Syntax for fromString input

input    ::= signed
signed   ::= -? unsigned
unsigned ::= ('0b' | '0B') binary
           | ('0o' | '0O') octal
           | ('0x' | '0X') hex
           | decimal
binary   ::= [0-1]+
octal    ::= [0-7]+
hex      ::= [0-9a-fA-F]+
decimal  ::= [0-9]+

For e.g.

fromString "0b10101101" == fromInt 173


fromString "-0o255" == fromInt -173


fromString "0XaD" == fromInt 173


fromString "173" == fromInt 173


fromString "b10101101" == Nothing
-- Because the leading '0' is missing.


fromString "-aD" == Nothing
-- Because 'a' is not a decimal digit.


fromString "0x" == Nothing
-- Because there must be at least one hexadecimal digit.
fromBinaryString : String -> Maybe Integer

Create the integer represented by the given signed binary string.

binary ::= -? [0-1]+

For e.g.

fromBinaryString "0" == Just zero


fromBinaryString "1010" == Just ten


fromBinaryString "-1010" == Just negativeTen


fromBinaryString "" == Nothing
-- Because the string is empty.


fromBinaryString "-" == Nothing
-- Because there must be at least one binary digit.


fromBinaryString "2" == Nothing
-- Because '2' is not a binary digit.
fromOctalString : String -> Maybe Integer

Create the integer represented by the given signed octal string.

octal ::= -? [0-7]+

For e.g.

fromOctalString "0" == Just zero


fromOctalString "12" == Just ten


fromOctalString "-12" == Just negativeTen


fromOctalString "" == Nothing
-- Because the string is empty.


fromOctalString "-" == Nothing
-- Because there must be at least one octal digit.


fromOctalString "8" == Nothing
-- Because '8' is not an octal digit.
fromDecimalString : String -> Maybe Integer

Create the integer represented by the given signed decimal string.

decimal ::= -? [0-9]+

For e.g.

fromDecimalString "0" == Just zero


fromDecimalString "10" == Just ten


fromDecimalString "-10" == Just negativeTen


fromDecimalString "" == Nothing
-- Because the string is empty.


fromDecimalString "-" == Nothing
-- Because there must be at least one decimal digit.


fromDecimalString "A" == Nothing
-- Because 'A' is not a decimal digit.
fromHexString : String -> Maybe Integer

Create the integer represented by the given signed hexadecimal string.

hex ::= -? [0-9a-fA-F]+

For e.g.

fromHexString "0" == Just zero


fromHexString "a" == Just ten


fromHexString "-A" == Just negativeTen


fromHexString "" == Nothing
-- Because the string is empty.


fromHexString "-" == Nothing
-- Because there must be at least one hexadecimal digit.


fromHexString "5g" == Nothing
-- Because 'g' is not a hexadecimal digit.
fromBaseBString : Int -> String -> Maybe Integer

Create the integer represented by the given signed base-b string.

b must be between 2 and 36 inclusive and each character in the string must be a valid base-b digit.

About base-b digits

A valid base-b digit is any digit d such that 0 <= d <= b - 1.

For bases larger than 10, you can use case-insensitive letters from the Latin alphabet to represent the base-b digits that are 10 or larger. So,

A or a represents 10
B or b represents 11
C or c represents 12
...
Z or z represents 35

For e.g.

If b = 16 then the valid base-16 digits are [0-9a-fA-F].

If b = 36 then the valid base-36 digits are [0-9a-zA-Z].

Syntax for fromBaseBString input

input ::= -? [digit]+
digit ::= [0-9a-zA-Z]

Valid strings when b = 16:

"0", "-0", "123", "-123", and "-Ff".

Invalid strings when b = 16:

  • "+2", because '+' is not part of the allowed syntax,
  • "5g", because 'g' is not a hexadecimal digit.

Examples

fromBaseBString 2 "1010" == Just ten


fromBaseBString 2 "-1010" == Just negativeTen


fromBaseBString 16 "aD" == fromInt 173


fromBaseBString 36 "z" == fromInt 35


fromBaseBString 2 "" == Nothing
-- Because the string is empty.


fromBaseBString 8 "-" == Nothing
-- Because there must be at least one octal digit.


fromBaseBString 10 "A" == Nothing
-- Because 'A' is not a decimal digit.

Comparison

To test for equality between two integers you can use == and /=.

add negativeFive two == negativeThree


mul negativeThree negativeThree /= negativeNine

For all other comparisons you will have to use the functions below.

compare : Integer -> Integer -> Order

Compare any two integers.

compare negativeFive negativeTwo == LT


compare two two == EQ


compare five negativeTen == GT

Determine if the second integer is less than the first.

(negativeFive |> isLessThan negativeTwo) == True


(two |> isLessThan two) == False


(five |> isLessThan negativeTen) == False

Determine if the second integer is less than or equal to the first.

(negativeFive |> isLessThanOrEqual negativeTwo) == True


(two |> isLessThanOrEqual two) == True


(five |> isLessThanOrEqual negativeTen) == False

Determine if the second integer is greater than the first.

(negativeFive |> isGreaterThan negativeTwo) == False


(two |> isGreaterThan two) == False


(five |> isGreaterThan negativeTen) == True

Determine if the second integer is greater than or equal to the first.

(negativeFive |> isGreaterThanOrEqual negativeTwo) == False


(two |> isGreaterThanOrEqual two) == True


(five |> isGreaterThanOrEqual negativeTen) == True

Find the larger of two integers.

max five negativeTen == five


max negativeFive negativeTwo == negativeTwo

Find the smaller of two integers.

min five negativeTen == negativeTen


min negativeFive negativeTwo == negativeFive

Predicates

Determine if the integer is negative (i.e. less than 0).

isNegative negativeTwo == True


isNegative zero == False


isNegative two == False

Determine if the integer is non-negative (i.e. not negative, so greater than or equal to 0).

isNonNegative negativeTwo == False


isNonNegative zero == True


isNonNegative two == True
isZero : Integer -> Bool

Determine if the integer is 0.

isZero zero == True


isZero negativeSeven == False


isZero six == False
isNonZero : Integer -> Bool

Determine if the integer is non-zero (i.e. not 0, so either positive or negative).

isNonZero zero == False


isNonZero negativeSeven == True


isNonZero six == True

Determine if the integer is positive (i.e. greater than 0).

isPositive five == True


isPositive zero == False


isPositive negativeEight == False

Determine if the integer is non-positive (i.e. not positive, so less than or equal to 0).

isNonPositive five == False


isNonPositive zero == True


isNonPositive negativeEight == True
isEven : Integer -> Bool

Determine if the integer is even (i.e. divisible by 2).

isEven zero == True


isEven negativeFour == True


isEven eight == True


isEven three == False


isEven negativeNine == False
isOdd : Integer -> Bool

Determine if the integer is odd (i.e. not even, so not divisible by 2).

isOdd zero == False


isOdd negativeFour == False


isOdd eight == False


isOdd three == True


isOdd negativeNine == True

Arithmetic

Compute the absolute value of the given integer. If you want it as a natural number, use toNatural.

You can think of the absolute value of an integer as its distance from 0.

abs zero == zero


abs five == five


abs negativeFive = five
-- Because 5 and -5 are the same distance away from 0.

Compute the additive inverse of the given integer.

The additive inverse of an integer, z, is the integer that, when added to z, yields 0.

negate five == negativeFive
-- Because 5 + (-5) = 0.


negate negativeFive == five
-- Because -5 + 5 = 0.


negate zero == zero
-- Becase 0 + 0 = 0.

Add two integers.

Subtract the second integer from the first.

sub ten four == six
-- 10 - 4 = 6


sub four ten == negativeSix
-- 4 - 10 = -6

Multiply two integers.

Find the quotient and remainder when the second integer (the dividend) is divided by the first (the divisor).

divModBy d D of two integers D and d ≠ 0, is defined as producing two unique integers q (the quotient) and r (the remainder) such that

  • d * q is the greatest multiple of d less than or equal to D, and
  • r = D - d * q such that 0 <= r < |d| (i.e. r is always non-negative).

For e.g.

(ten |> divModBy two) == Just ( five, zero )


(ten |> divModBy negativeTwo) == Just ( negativeFive, zero )


(negativeTen |> divModBy two) == Just ( negativeFive, zero )


(negativeTen |> divModBy negativeTwo) == Just ( five, zero )


(ten |> divModBy three) == Just ( three, one )


(ten |> divModBy negativeThree) == Just ( negativeThree, one )


(negativeTen |> divModBy three) == Just ( negativeFour, two )


(negativeTen |> divModBy negativeThree) == Just ( four, two )

Division by 0 is not allowed. So, for all z : Integer,

(z |> divModBy zero) == Nothing

N.B. divModBy defines Euclidean division (or E-division) according to Daan Leijen's paper, Division and Modulus for Computer Scientists.

Find the quotient when the second integer is divided by the first.

N.B. Please see divModBy to understand how the quotient is computed.

Find the remainder when the second integer is divided by the first.

N.B. Please see divModBy to understand how the remainder is computed.

Find the quotient and remainder when the second integer (the dividend) is divided by the first (the divisor).

quotRemBy d D of two integers D and d ≠ 0, is defined as producing two unique integers q (the quotient) and r (the remainder) such that

  • |d * q| is the greatest multiple of d less than or equal to |D|, and
  • r = D - d * q such that 0 <= |r| < |d| (i.e. r can be negative).

For e.g.

(ten |> quotRemBy two) == Just ( five, zero )


(ten |> quotRemBy negativeTwo) == Just ( negativeFive, zero )


(negativeTen |> quotRemBy two) == Just ( negativeFive, zero )


(negativeTen |> quotRemBy negativeTwo) == Just ( five, zero )


(ten |> quotRemBy three) == Just ( three, one )


(ten |> quotRemBy negativeThree) == Just ( negativeThree, one )


(negativeTen |> quotRemBy three) == Just ( negativeThree, negativeOne )


(negativeTen |> quotRemBy negativeThree) == Just ( three, negativeOne )

Division by 0 is not allowed. So, for all z : Integer,

(z |> quotRemBy zero) == Nothing

N.B. quotRemBy defines truncated division (or T-division) according to Daan Leijen's paper, Division and Modulus for Computer Scientists.

Find the quotient when the second integer is divided by the first.

N.B. Please see quotRemBy to understand how the quotient is computed.

Find the remainder when the second integer is divided by the first.

N.B. Please see quotRemBy to understand how the remainder is computed.

exp : Integer -> Natural -> Integer

Integer exponentiation. Find the power of the integer (the base) to the natural number (the exponent).

Given,

import Natural as N

Then,

exp two N.three == eight


exp negativeTwo N.three == negativeEight

For all z : Integer,

exp z N.zero == one

In particular,

exp zero N.zero == one

N.B. You can read "What is 0^0?" to learn more.

For all n : Natural, where n is positive,

exp zero n == zero

Conversion

toInt : Integer -> Int

Convert any integer, z, to sign z * (|z| mod (maxSafeInt + 1)), where

sign z =
    -1 if z < 0
     0 if z = 0
     1 if z > 0

For e.g.

toInt zero == 0


toInt ten == 10


toInt negativeTen == -10


toInt (fromSafeInt maxSafeInt) == maxSafeInt


toInt (fromSafeInt minSafeInt) == minSafeInt


toInt (add (fromSafeInt maxSafeInt) one) == 0


toInt (add (fromSafeInt maxSafeInt) ten) == 9


toInt (sub (fromSafeInt minSafeInt) one) == 0


toInt (sub (fromSafeInt minSafeInt) ten) == -9
toNatural : Integer -> Natural

Compute the absolute value of the given integer as a natural number. If you want an integer, use abs.

toString : Integer -> String

An alias for toDecimalString.

Convert any integer to its signed binary (base-2) representation.

toBinaryString zero == "0"


toBinaryString one == "1"


toBinaryString ten == "1010"


toBinaryString negativeTen == "-1010"


toBinaryString (fromSafeInt -1729) == "-11011000001"


toBinaryString (add (fromSafeInt maxSafeInt) one) == "100000000000000000000000000000000000000000000000000000"


toBinaryString (sub (fromSafeInt minSafeInt) one) == "-100000000000000000000000000000000000000000000000000000"

Convert any integer to its signed octal (base-8) representation.

toOctalString zero == "0"


toOctalString one == "1"


toOctalString ten == "12"


toOctalString negativeTen == "-12"


toOctalString (fromSafeInt -1729) == "-3301"


toOctalString (add (fromSafeInt maxSafeInt) one) == "400000000000000000"


toOctalString (sub (fromSafeInt minSafeInt) one) == "-400000000000000000"

Convert any integer to its signed decimal (base-10) representation.

toDecimalString zero == "0"


toDecimalString one == "1"


toDecimalString ten == "10"


toDecimalString negativeTen == "-10"


toDecimalString (fromSafeInt -1729) == "-1729"


toDecimalString (add (fromSafeInt maxSafeInt) one) == "9007199254740992"


toDecimalString (sub (fromSafeInt minSafeInt) one) == "-9007199254740992"
toHexString : Integer -> String

Convert any integer to its signed hexadecimal (base-16) representation.

toHexString zero == "0"


toHexString one == "1"


toHexString ten == "A"


toHexString negativeTen == "-A"


toHexString (fromSafeInt -1729) == "-6C1"


toHexString (add (fromSafeInt maxSafeInt) one) == "20000000000000"


toHexString (sub (fromSafeInt minSafeInt) one) == "-20000000000000"
toBaseBString : Int -> Integer -> Maybe String

Convert any integer to its signed base-b representation.

b must be between 2 and 36 inclusive and each character in the resulting string will be a valid base-b digit.

All Latin letters in the base-b representation will be uppercased.

For e.g.

toBaseBString 2 (fromSafeInt 1729) == Just "11011000001"


toBaseBString 8 (fromSafeInt -1729) == Just "-3301"


toBaseBString 10 (fromSafeInt 1729) == Just "1729"


toBaseBString 16 (fromSafeInt -1729) == Just "-6C1"


toBaseBString 36 (fromSafeInt 1729) == Just "1C1"

For any k : Int where k < 2 or k > 36, and any z : Integer,

toBaseBString k z == Nothing

N.B. Please refer to fromBaseBString to learn more about base-b digits.