File: README.md

package info (click to toggle)
haskell-integer-roots 1.0.4.0-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 264 kB
  • sloc: haskell: 1,591; makefile: 3
file content (100 lines) | stat: -rw-r--r-- 2,897 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# integer-roots [![Hackage](http://img.shields.io/hackage/v/integer-roots.svg)](https://hackage.haskell.org/package/integer-roots) [![Stackage LTS](http://stackage.org/package/integer-roots/badge/lts)](http://stackage.org/lts/package/integer-roots) [![Stackage Nightly](http://stackage.org/package/integer-roots/badge/nightly)](http://stackage.org/nightly/package/integer-roots)

Calculating integer roots and testing perfect powers of arbitrary precision.

## Integer square root

The [integer square root](https://en.wikipedia.org/wiki/Integer_square_root)
(`integerSquareRoot`)
of a non-negative integer
$n$
is the greatest integer
$m$
such that
$m\le\sqrt{n}$.
Alternatively, in terms of the
[floor function](https://en.wikipedia.org/wiki/Floor_and_ceiling_functions),
$m = \lfloor\sqrt{n}\rfloor$.

For example,

```haskell
> integerSquareRoot 99
9
> integerSquareRoot 101
10
```

It is tempting to implement `integerSquareRoot` via `sqrt :: Double -> Double`:

```haskell
integerSquareRoot :: Integer -> Integer
integerSquareRoot = truncate . sqrt . fromInteger
```

However, this implementation is faulty:

```haskell
> integerSquareRoot (3037000502^2)
3037000501
> integerSquareRoot (2^1024) == 2^1024
True
```

The problem here is that `Double` can represent only
a limited subset of integers without precision loss.
Once we encounter larger integers, we lose precision
and obtain all kinds of wrong results.

This library features a polymorphic, efficient and robust routine
`integerSquareRoot :: Integral a => a -> a`,
which computes integer square roots by
[Karatsuba square root algorithm](https://hal.inria.fr/inria-00072854/PDF/RR-3805.pdf)
without intermediate `Double`s.

## Integer cube roots

The integer cube root
(`integerCubeRoot`)
of an integer
$n$
equals to
$\lfloor\sqrt[3]{n}\rfloor$.

Again, a naive approach is to implement `integerCubeRoot`
via `Double`-typed computations:

```haskell
integerCubeRoot :: Integer -> Integer
integerCubeRoot = truncate . (** (1/3)) . fromInteger
```

Here the precision loss is even worse than for `integerSquareRoot`:

```haskell
> integerCubeRoot (4^3)
3
> integerCubeRoot (5^3)
4
```

That is why we provide a robust implementation of
`integerCubeRoot :: Integral a => a -> a`,
which computes roots by
[generalized Heron algorithm](https://en.wikipedia.org/wiki/Nth_root_algorithm).

## Higher powers

In spirit of `integerSquareRoot` and `integerCubeRoot` this library
covers the general case as well, providing
`integerRoot :: (Integral a, Integral b) => b -> a -> a`
to compute integer $k$-th roots of arbitrary precision.

There is also `highestPower` routine, which tries hard to represent
its input as a power with as large exponent as possible. This is a useful function
in number theory, e. g., elliptic curve factorisation.

```haskell
> map highestPower [2..10]
[(2,1),(3,1),(2,2),(5,1),(6,1),(7,1),(2,3),(3,2),(10,1)]
```