https://github.com/cypherpoet/modulusoperandi
Declarative modular arithmetic for Swift Integers and Floating-Point types that supports Euclidean, flooring, and truncating division algorithms.
https://github.com/cypherpoet/modulusoperandi
math modulo-arithmetics modulus swift swift-math swift-modulus swift-package-manager swift-packages
Last synced: 11 months ago
JSON representation
Declarative modular arithmetic for Swift Integers and Floating-Point types that supports Euclidean, flooring, and truncating division algorithms.
- Host: GitHub
- URL: https://github.com/cypherpoet/modulusoperandi
- Owner: CypherPoet
- License: mit
- Created: 2020-10-18T23:39:59.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2020-11-15T16:56:09.000Z (about 5 years ago)
- Last Synced: 2025-02-18T20:47:32.480Z (12 months ago)
- Topics: math, modulo-arithmetics, modulus, swift, swift-math, swift-modulus, swift-package-manager, swift-packages
- Language: Swift
- Homepage:
- Size: 5.3 MB
- Stars: 3
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# 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](https://en.wikipedia.org/wiki/Modulo_operation#Variants_of_the_definition). Furthermore, Swift's built-in `%` operator — while used as a modulus in some languages — is [strictly used as a _remainder_ operator](https://docs.swift.org/swift-book/LanguageGuide/BasicOperators.html#ID64).
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](https://en.wikipedia.org/wiki/Euclidean_division#Division_theorem), [Truncating](https://developer.apple.com/documentation/swift/float/2886166-truncatingremainder), or [Flooring](https://www.sololearn.com/Discuss/1453039/floor-division-and-modulo-operator) 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:
```swift
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**
```swift
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
```
```swift
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
```
```swift
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:
See Help Menu
```sh
modulo --help
```
```sh
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 [--euclidean] [--flooring] [--truncating]
ARGUMENTS:
The dividend to perform division against.
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](https://github.com/apple/swift-argument-parser/issues/31). 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`:
```sh
modulo \ -5 4
```
`-5 mod -4`:
```sh
modulo \ -5 \ -4
```
`5 mod -4`:
```sh
modulo 5 \ -4
```
## Contributing
Contributions to `ModulusOperandi` are most welcome. Check out some of the [issue templates](./.github/ISSUE_TEMPLATE/) for more info.
## Developing
### Requirements
- Xcode 12.0+ (for developing)
### Generating Documentation
Documentation is generated by [Jazzy](https://github.com/realm/jazzy). Installation instructions can be found [here](https://github.com/realm/jazzy#installation), 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](./.github/workflows/PublishDocumentation.yml) 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](./LICENSE) for more info.