# ModulusOperandi

*Declarative, multi-algorithm modular arithmetic for Swift Integers and Floating-Point types.*

Modular arithmetic algorithms come in variants that use either Euclidean, truncating, or flooring division. Furthermore, Swift's built-in `%`

operator — while used as a modulus in some languages — is strictly used as a *remainder* operator.

These nuances can lead modular arithmetic code that's ambiguous in both intent and correctness — which is what `ModulusOperandi`

attempts to solve.

## Features

- ✅ Declarative API that allows for choosing between Euclidean, Truncating, or Flooring Modular Arithmetic.
- ✅ Euclidean by default.
- ✅ Support for conformances to
`BinaryInteger`

and`FloatingPointInteger`

. - ✅ Command Line tool for performing calculations in the Terminal.

## Installation

### Xcode Projects

Select `File`

-> `Swift Packages`

-> `Add Package Dependency`

and enter `https://github.com/CypherPoet/ModulusOperandi`

.

### Swift Package Manager Projects

You can add `ModulusOperandi`

as a dependency in your `Package.swift`

file:

```
let package = Package(
//...
dependencies: [
.package(url: "https://github.com/CypherPoet/ModulusOperandi", from: "0.2.2"),
],
//...
)
```

Then simply `import ModulusOperandi`

wherever you’d like to use it.

## Usage

After importing `ModulusOperandi`

in a file, types that conform to `BinaryInteger`

and `FloatingPointInteger`

will be extended with a `modulus`

function.

This function treats its value as the `dividend`

and takes a `divisor`

of the same type. It also takes an optional `mode`

argument to choose between Euclidean, Truncating, or Flooring Modular Arithmetic.

**By default, the mode will be Euclidean**

```
import ModulusOperandi
let dividend = 5
let divisor = 3
dividend.modulo(divisor) // 2
dividend.modulo(-divisor) // 2
-dividend.modulo(divisor) // -2
-dividend.modulo(-divisor) // -2
// Same as...
dividend.modulo(divisor, mode: .euclidean) // 2
dividend.modulo(-divisor, mode: .euclidean) // 2
-dividend.modulo(divisor, mode: .euclidean) // -2
-dividend.modulo(-divisor, mode: .euclidean) // -2
```

```
import ModulusOperandi
let dividend = 5
let divisor = 3
dividend.modulo(3, mode: .flooring) // 2
dividend.modulo(-3, mode: .flooring) // -1
-dividend.modulo(3, mode: .flooring) // -2
-dividend.modulo(-3, mode: .flooring) // 1
```

```
import ModulusOperandi
let dividend = 5
let divisor = 3
dividend.modulo(3, mode: .truncating) // 2
dividend.modulo(-3, mode: .truncating) // 2
-dividend.modulo(3, mode: .truncating) // -2
-dividend.modulo(-3, mode: .truncating) // -2
```

## Command Line Tool

`ModulusOperandi`

also ships with a command line tool that lets you perform calculations directly from the command line.

To install it, clone the project and run `make`

:

```
$ git clone git@github.com:CypherPoet/ModulusOperandi.git
$ cd ModulusOperandiCLI
$ make
```

The command line tool will be installed as `modulo`

, and running `modulo --help`

will present some helpful usage instructions:

```
modulo --help
```

```
OVERVIEW: Multi-algorithm modular arithmetic for Swift integers and
floating-Point types.
Modular arithmetic algorithms come in variants that use either Euclidean,
truncating, or flooring division.
This tool acts as a CLI for the `ModulusOperandi` Swift package -- which allows
you to perform modular arithmetic according to your desired algorithm.
📝 Note on Negative Numbers
----------------------------------------------
To use negative numbers, prefix the argument with `\ ` (including the space).
For example, -5 mod 4 would be passed as:
modulo \ -5 4
-5 mod -4 would be passed as:
modulo \ -5 \ -4
🔗 More Info On Modular Arithmetic
----------------------------------------------
- https://en.wikipedia.org/wiki/Modulo_operation#Variants_of_the_definition
USAGE: modulo <dividend> <divisor> [--euclidean] [--flooring] [--truncating]
ARGUMENTS:
<dividend> The dividend to perform division against.
<divisor> The divisor to use as a "modulus".
OPTIONS:
--euclidean/--flooring/--truncating
The algorithm to use for computing results. (default:
euclidean)
--version Show the version.
-h, --help Show help information.
```

### Negative Numbers

Disambiguating negative numbers from argument flags is a notorious challenge for Command Line interfaces. Currently, support for this in Swift's Argument Parser appears to be an ongoing area of development. In the meantime, though, the `modulo`

command can take negative-number arguments via some clever escape syntax.

**Simply prefix any negative number with \ (including the space). Like so:**

`-5 mod 4`

:

```
modulo \ -5 4
```

`-5 mod -4`

:

```
modulo \ -5 \ -4
```

`5 mod -4`

:

```
modulo 5 \ -4
```

## Contributing

Contributions to `ModulusOperandi`

are most welcome. Check out some of the issue templates for more info.

## Developing

### Requirements

- Xcode 12.0+ (for developing)

### Generating Documentation

Documentation is generated by Jazzy. Installation instructions can be found here, and as soon as you have it set up, docs can be generated simply by running `jazzy`

from the command line.

📝 Note that this will only generate the `docs`

folder for you to view locally. This folder is being ignored by `git`

, as an action exists to automatically generate docs and serve them on the project's `gh-pages`

branch.

## License

`ModulusOperandi`

is available under the MIT license. See the LICENSE file for more info.