## ModulusOperandi

### master

Declarative modular arithmetic for Swift Integers and Floating-Point types that supports Euclidean, flooring, and truncating division algorithms.

# 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

----------------------------------------------
- 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.

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