GithubHelp home page GithubHelp logo

cypherpoet / modulusoperandi Goto Github PK

View Code? Open in Web Editor NEW
3.0 3.0 1.0 5.43 MB

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

License: MIT License

Swift 99.15% Shell 0.32% Makefile 0.53%
swift swift-package-manager swift-packages swift-modulus modulus modulo-arithmetics swift-math math

modulusoperandi's Introduction

ModulusOperandi

Banner Logo

Twitter: @cypher_poet

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 CLI Examples

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 [email protected]: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
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.

modulusoperandi's People

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.