A pure Elm library for computing with the natural numbers, ℕ = { 0, 1, 2, ... }.
zero
one
two
three
four
five
six
seven
eight
nine
ten
fromSafeInt
fromInt
fromSafeString
fromString
(supports binary, octal, decimal, and hexadecimal inputs)fromBinaryString
fromOctalString
fromDecimalString
fromHexString
fromBaseBString
==
/=
compare
isLessThan
isLessThanOrEqual
isGreaterThan
isGreaterThanOrEqual
max
min
isZero
(i.e.== 0
)isOne
(i.e.== 1
)isPositive
(i.e.> 0
)isEven
isOdd
add
sub
(saturating subtraction)mul
divModBy
(Euclidean division)divBy
modBy
exp
toInt
(use with caution since it discards information)
toString
(same astoDecimalString
)toBinaryString
toOctalString
toDecimalString
toHexString
toBaseBString
The factorial of a natural number n
, denoted by n!
, is the product of all
positive natural numbers less than or equal to n
. The value of 0!
is 1
by convention.
import Natural as N exposing (Natural)
fact : Natural -> Natural
fact n =
if N.isZero n then
N.one
else
N.mul n <| fact (N.sub n N.one)
N.toString (fact (N.fromSafeInt 100)) == "93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000"
A few more examples can be found in the examples/src
directory.
Fibonacci.elm
- Computes up to the 1000th Fibonacci number.Pi.elm
- Computes the first 100 digits ofπ
.E.elm
- Computes the first 100 digits ofe
.BaseConversion.elm
- Converts decimal numbers to their binary, octal, and hexadecimal representations.
This library tries to provide a reasonably efficient implementation of extended-precision arithmetic over the natural numbers while being written purely in Elm and making extensive use of lists. Within that context it gives reasonable performance.
Natural / comparison
compare (2^26)^9999-1 and (2^26)^9999-2
runs/second = 5,839
goodness of fit = 99.86%
Natural / multiplication
999..9 (100 9's) * 999..9 (100 9's)
runs/second = 53,038
goodness of fit = 99.79%
Natural / division with remainder
(999..9 (100 9's))^2 / 999..9 (100 9's)
runs/second = 6,852
goodness of fit = 99.91%
Natural / exponentiation
2 ^ 1000
runs/second = 15,623
goodness of fit = 99.7%
N.B. You can read benchmarks/README.md
to learn how to reproduce the above benchmark report and
to see how this library compares against cmditch/elm-bigint
.
- Chapter 17 - Extended-Precision Arithmetic of C Interfaces and Implementations: Techniques for Creating Reusable Software helped me to design, organize and implement the library.
- Lua Bint inspired the examples.
- Per Brinch Hansen, Multiple-Length Division Revisited: A Tour of the Minefield helped me implement an efficient divide-and-correct algorithm for division with remainder.