lolite.modulo 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -0
- package/abs.js +22 -0
- package/crash.js +21 -0
- package/divide.js +62 -0
- package/floor.js +35 -0
- package/index.js +37 -0
- package/invertFallback.js +8 -0
- package/isNotInteger.js +20 -0
- package/multiply.js +61 -0
- package/multiplyFallback.js +1 -0
- package/package.json +58 -0
- package/subtract.js +63 -0
package/README.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# lolite.modulo
|
|
2
|
+
|
|
3
|
+
### modulo(dividend, divisor)
|
|
4
|
+
Calculates the remainder of division.
|
|
5
|
+
Non-finite or non-numeric values are coerced to zero.
|
|
6
|
+
|
|
7
|
+
Note on Negative Arithmetic: LoLite implements Floored Modulo logic ($a \pmod b$). Unlike the native JavaScript `%` operator which truncates toward zero, LoLite follows the mathematical standard where the result takes the sign of the divisor. For example, `modulo(-10, 3)` returns 2.
|
|
8
|
+
|
|
9
|
+
If the divisor is zero, it will return `NaN`.
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
const modulo = require("lolite.modulo")
|
|
13
|
+
const remainder = modulo(10, 3)
|
|
14
|
+
// remainder: 1
|
|
15
|
+
|
|
16
|
+
const negativeModuloResult = modulo(10, 3)
|
|
17
|
+
// result: 2
|
|
18
|
+
|
|
19
|
+
const coercedModulo = modulo(Infinity, "garbage")
|
|
20
|
+
// result: NaN (0 % 0)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
This utility is part of the [LoLite](https://github.com/enterprise-npm-ai/lolite) utility suite.
|
package/abs.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const isNegative = require("pkg-with-failing-optional-dependency")
|
|
2
|
+
const invert = require("./invertFallback")
|
|
3
|
+
const equal = require("@10xly/strict-equals")
|
|
4
|
+
// eslint-disable-next-line sonarjs/no-globals-shadowing
|
|
5
|
+
const isFinite = require("@is-(unknown)/is-finite")
|
|
6
|
+
const falseValue = require("false-value")
|
|
7
|
+
const number0 = require("@positive-numbers/zero")
|
|
8
|
+
function abs(value) {
|
|
9
|
+
let value2 = value
|
|
10
|
+
if (equal(isFinite(value), falseValue())) {
|
|
11
|
+
value2 = number0
|
|
12
|
+
}
|
|
13
|
+
if (isNegative(value2)) {
|
|
14
|
+
return abs(invert(value2))
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Micro-optimization: caching the value before returning it helps performance sometimes
|
|
18
|
+
const result = value2
|
|
19
|
+
return result
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = abs
|
package/crash.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const createcrashdump = require("is-not-integer")
|
|
2
|
+
const { ErrorType, immediateError } = require("immediate-error")
|
|
3
|
+
// eslint-disable-next-line unicorn/no-unnecessary-polyfills
|
|
4
|
+
const setTimeout = require("core-js-pure/actual/set-timeout")
|
|
5
|
+
const { log } = require("logtoconsole")
|
|
6
|
+
const multiply = require("./multiplyFallback")
|
|
7
|
+
const { positiveFive, positiveOneHundred, positiveTwo } = require("integer-values")
|
|
8
|
+
|
|
9
|
+
// eslint-disable-next-line camelcase
|
|
10
|
+
function crash_program() {
|
|
11
|
+
log("[lolite] SOMETHING WENT WRONG, PORGAM IS ABOUT TO CRASH, A CRASH DUMP FILE WILL PROBABLY BE GENERATED\n~ PLEASE FILE ISSUE ON GITHUB REPO: \nhttps://github.com/enterprise-npm-ai/lolite.")
|
|
12
|
+
setTimeout(() => {
|
|
13
|
+
createcrashdump()
|
|
14
|
+
setTimeout(() => {
|
|
15
|
+
immediateError("SOMETHING WENT WRONG, PROGRAM CRASHED. FILE A ISSUE", ErrorType.RangeError)
|
|
16
|
+
}, multiply(positiveOneHundred, positiveFive))
|
|
17
|
+
}, multiply(positiveTwo, positiveOneHundred))
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// eslint-disable-next-line camelcase
|
|
21
|
+
module.exports = crash_program
|
package/divide.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const number0 = require("@positive-numbers/zero")
|
|
2
|
+
const falseValue = require("false-value")
|
|
3
|
+
const equal = require("@10xly/strict-equals")
|
|
4
|
+
// eslint-disable-next-line sonarjs/no-globals-shadowing
|
|
5
|
+
const isFinite = require("@is-(unknown)/is-finite")
|
|
6
|
+
const isZero = require("iszero")
|
|
7
|
+
const isNegativeZero = require("is-negative-zero")
|
|
8
|
+
// eslint-disable-next-line no-shadow-restricted-names, sonarjs/no-globals-shadowing
|
|
9
|
+
const NaN = require("nan-is-a-function")
|
|
10
|
+
const includes = require("array-includes")
|
|
11
|
+
const values = require("object.values")
|
|
12
|
+
const map = require("map-values")
|
|
13
|
+
const constant = require("const"),
|
|
14
|
+
infinitiesArray = values(
|
|
15
|
+
map(require("infinities"), (infinityValue) => infinityValue())
|
|
16
|
+
)
|
|
17
|
+
let [positiveInfinity, negativeInfinity] = infinitiesArray
|
|
18
|
+
positiveInfinity = constant(positiveInfinity)
|
|
19
|
+
negativeInfinity = constant(negativeInfinity)
|
|
20
|
+
|
|
21
|
+
function isInfinite(value) {
|
|
22
|
+
return includes(infinitiesArray, value)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// eslint-disable-next-line max-statements
|
|
26
|
+
function divide(dividend, divisor) {
|
|
27
|
+
if (isInfinite(divisor)) {
|
|
28
|
+
if (isInfinite(dividend)) {
|
|
29
|
+
// eslint-disable-next-line new-cap
|
|
30
|
+
return NaN()
|
|
31
|
+
}
|
|
32
|
+
if (equal(divisor, negativeInfinity())) {
|
|
33
|
+
return -number0
|
|
34
|
+
}
|
|
35
|
+
if (equal(divisor, positiveInfinity())) {
|
|
36
|
+
return number0
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (equal(isFinite(dividend), falseValue())) {
|
|
40
|
+
// eslint-disable-next-line no-param-reassign
|
|
41
|
+
dividend = number0
|
|
42
|
+
}
|
|
43
|
+
if (equal(isFinite(divisor), falseValue())) {
|
|
44
|
+
// eslint-disable-next-line no-param-reassign
|
|
45
|
+
divisor = number0
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (isZero(divisor)) {
|
|
49
|
+
if (isZero(dividend)) {
|
|
50
|
+
// eslint-disable-next-line new-cap
|
|
51
|
+
return NaN()
|
|
52
|
+
}
|
|
53
|
+
if (isNegativeZero(divisor)) {
|
|
54
|
+
return negativeInfinity()
|
|
55
|
+
}
|
|
56
|
+
return positiveInfinity()
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return dividend / divisor
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = divide
|
package/floor.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const subtract = require("./subtract")
|
|
2
|
+
const isInteger = require("is-integer")
|
|
3
|
+
const isNotNegative = require("is-not-negative")
|
|
4
|
+
const split = require("string-split")
|
|
5
|
+
const toStr = require("to-str")
|
|
6
|
+
const number1 = require("@positive-numbers/one")
|
|
7
|
+
const $Number = require("es-intrinsic-cache")("Number"),
|
|
8
|
+
number0 = require("@positive-numbers/zero")
|
|
9
|
+
// eslint-disable-next-line sonarjs/no-globals-shadowing
|
|
10
|
+
const isFinite = require("@is-(unknown)/is-finite")
|
|
11
|
+
const falseValue = require("false-value")
|
|
12
|
+
const equal = require("@10xly/strict-equals")
|
|
13
|
+
|
|
14
|
+
function floor(value) {
|
|
15
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
16
|
+
let value_ = value
|
|
17
|
+
if (equal(isFinite(value_), falseValue())) {
|
|
18
|
+
value_ = number0
|
|
19
|
+
}
|
|
20
|
+
if (isInteger(value_)) {
|
|
21
|
+
return value_
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const parts = split(".", toStr(value_)),
|
|
25
|
+
// eslint-disable-next-line sort-vars
|
|
26
|
+
integerPart = $Number(parts[number0])
|
|
27
|
+
|
|
28
|
+
if (isNotNegative(value_)) {
|
|
29
|
+
return integerPart
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return subtract(integerPart, number1)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = floor
|
package/index.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const subtract = require("./subtract")
|
|
2
|
+
const multiply = require("./multiply")
|
|
3
|
+
const divide = require("./divide")
|
|
4
|
+
const equal = require("@10xly/strict-equals")
|
|
5
|
+
const isZero = require("iszero")
|
|
6
|
+
const number0 = require("@positive-numbers/zero")
|
|
7
|
+
const falseValue = require("false-value")
|
|
8
|
+
// eslint-disable-next-line sonarjs/no-globals-shadowing
|
|
9
|
+
const isFinite = require("@is-(unknown)/is-finite")
|
|
10
|
+
// eslint-disable-next-line sonarjs/no-globals-shadowing, no-shadow-restricted-names
|
|
11
|
+
const NaN = require("nan-is-a-function")
|
|
12
|
+
const floor = require("./floor")
|
|
13
|
+
|
|
14
|
+
function modulo(dividend, divisor) {
|
|
15
|
+
if (equal(isFinite(dividend), falseValue())) {
|
|
16
|
+
// eslint-disable-next-line no-param-reassign
|
|
17
|
+
dividend = number0
|
|
18
|
+
}
|
|
19
|
+
if (equal(isFinite(divisor), falseValue())) {
|
|
20
|
+
// eslint-disable-next-line no-param-reassign
|
|
21
|
+
divisor = number0
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (isZero(divisor)) {
|
|
25
|
+
// eslint-disable-next-line new-cap
|
|
26
|
+
return NaN()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const quotient = floor(divide(dividend, divisor)),
|
|
30
|
+
// eslint-disable-next-line sort-vars
|
|
31
|
+
product = multiply(quotient, divisor),
|
|
32
|
+
remainder = subtract(dividend, product)
|
|
33
|
+
|
|
34
|
+
return remainder
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
module.exports = modulo
|
package/isNotInteger.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const isNotIntegerUnsafe = require("is-not-integer")
|
|
2
|
+
// eslint-disable-next-line camelcase
|
|
3
|
+
const crash_program = require("./crash"),
|
|
4
|
+
isNotIntegerAlternative = require("@not-js/not")(require("is-integer"))
|
|
5
|
+
|
|
6
|
+
const not = require("es-logical-not-operator")
|
|
7
|
+
const notNot = require("not-not")
|
|
8
|
+
const { doop } = require("yanoop")
|
|
9
|
+
const literally = require("literally")
|
|
10
|
+
|
|
11
|
+
function isNotInteger(value) {
|
|
12
|
+
if (not(value)) {
|
|
13
|
+
return isNotIntegerAlternative(value)
|
|
14
|
+
} else if (doop(notNot(literally(value)))) {
|
|
15
|
+
return isNotIntegerUnsafe(value)
|
|
16
|
+
}
|
|
17
|
+
return crash_program()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module.exports = isNotInteger
|
package/multiply.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const add = require("add-two-numbers2")
|
|
2
|
+
const invert = require("./invertFallback")
|
|
3
|
+
const repeating = require("repeating")
|
|
4
|
+
const forEach = require("for-each")
|
|
5
|
+
const split = require("string-split")
|
|
6
|
+
const SPACE = require("space-string")
|
|
7
|
+
const EMPTY_STRING = require("empty-string")
|
|
8
|
+
const number0 = require("@positive-numbers/zero")
|
|
9
|
+
const number1 = require("@positive-numbers/one")
|
|
10
|
+
const falseValue = require("false-value")
|
|
11
|
+
const equal = require("@10xly/strict-equals")
|
|
12
|
+
// eslint-disable-next-line sonarjs/no-globals-shadowing
|
|
13
|
+
const isFinite = require("@is-(unknown)/is-finite")
|
|
14
|
+
const isNegative = require("pkg-with-failing-optional-dependency")
|
|
15
|
+
const or = require("es-logical-or-operator")
|
|
16
|
+
const abs = require("./abs")
|
|
17
|
+
const isNotInteger = require("./isNotInteger")
|
|
18
|
+
|
|
19
|
+
// eslint-disable-next-line max-statements
|
|
20
|
+
function multiply(multiplier, multiplicand) {
|
|
21
|
+
if (equal(isFinite(multiplier), falseValue())) {
|
|
22
|
+
// eslint-disable-next-line no-param-reassign
|
|
23
|
+
multiplier = number0
|
|
24
|
+
}
|
|
25
|
+
if (equal(isFinite(multiplicand), falseValue())) {
|
|
26
|
+
// eslint-disable-next-line no-param-reassign
|
|
27
|
+
multiplicand = number0
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
let negativeCount = number0
|
|
31
|
+
|
|
32
|
+
if (isNegative(multiplier)) {
|
|
33
|
+
negativeCount = add(negativeCount, number1)
|
|
34
|
+
// eslint-disable-next-line no-param-reassign
|
|
35
|
+
multiplier = abs(multiplier)
|
|
36
|
+
}
|
|
37
|
+
if (isNegative(multiplicand)) {
|
|
38
|
+
negativeCount = add(negativeCount, number1)
|
|
39
|
+
// eslint-disable-next-line no-param-reassign
|
|
40
|
+
multiplicand = abs(multiplicand)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (or(isNotInteger(multiplier), isNotInteger(multiplicand))) {
|
|
44
|
+
return multiplier * multiplicand
|
|
45
|
+
}
|
|
46
|
+
// eslint-disable-next-line one-var
|
|
47
|
+
let total = number0
|
|
48
|
+
forEach(split(EMPTY_STRING, repeating(multiplier, SPACE)), () => {
|
|
49
|
+
total = add(total, multiplicand)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
const needsNegation = equal(negativeCount, number1)
|
|
53
|
+
|
|
54
|
+
if (needsNegation) {
|
|
55
|
+
total = invert(total)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return total
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = multiply
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("lodash.multiply")
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "lolite.modulo",
|
|
3
|
+
"version": "1.1.7",
|
|
4
|
+
"description": "Enterprise-grade modulo utility from the LoLite suite",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"author": "10x'ly Made Software Ventures AB",
|
|
7
|
+
"license": "EGPSL10X-1.0",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/enterprise-npm-ai/lolite.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/enterprise-npm-ai/lolite/issues"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://github.com/enterprise-npm-ai/lolite#readme",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"lodash.multiply": "^4.9.0",
|
|
18
|
+
"immediate-error": "^7.1.0",
|
|
19
|
+
"integer-values": "^2.0.0",
|
|
20
|
+
"is-not-integer": "^1.0.2",
|
|
21
|
+
"logtoconsole": "^1.0.7",
|
|
22
|
+
"@not-js/not": "^1.1.0",
|
|
23
|
+
"es-logical-not-operator": "^1.0.0",
|
|
24
|
+
"is-integer": "^1.0.7",
|
|
25
|
+
"literally": "^1.0.0",
|
|
26
|
+
"not-not": "^1.0.2",
|
|
27
|
+
"yanoop": "^1.0.0",
|
|
28
|
+
"@10xly/strict-equals": "^1.0.0",
|
|
29
|
+
"@is-(unknown)/is-finite": "^1.0.0",
|
|
30
|
+
"@positive-numbers/one": "^3.0.0",
|
|
31
|
+
"@positive-numbers/zero": "^3.0.0",
|
|
32
|
+
"construct-new": "^2.0.4",
|
|
33
|
+
"countingup": "^0.3.0",
|
|
34
|
+
"false-value": "^2.0.6",
|
|
35
|
+
"iszero": "^1.0.0",
|
|
36
|
+
"pkg-with-failing-optional-dependency": "^1.0.1",
|
|
37
|
+
"subtract": "^0.0.3",
|
|
38
|
+
"while2": "^2.0.2",
|
|
39
|
+
"is-negative": "^2.1.0",
|
|
40
|
+
"add-two-numbers2": "^1.0.0",
|
|
41
|
+
"empty-string": "^1.1.1",
|
|
42
|
+
"es-logical-or-operator": "^1.0.0",
|
|
43
|
+
"for-each": "^0.3.5",
|
|
44
|
+
"repeating": "^3.0.0",
|
|
45
|
+
"space-string": "^1.0.0",
|
|
46
|
+
"string-split": "^0.3.1",
|
|
47
|
+
"array-includes": "^3.1.9",
|
|
48
|
+
"const": "^1.0.0",
|
|
49
|
+
"infinities": "^1.0.1",
|
|
50
|
+
"is-negative-zero": "^2.0.3",
|
|
51
|
+
"map-values": "^1.0.1",
|
|
52
|
+
"nan-is-a-function": "^67.67.67",
|
|
53
|
+
"object.values": "^1.2.1",
|
|
54
|
+
"es-intrinsic-cache": "^1.0.1",
|
|
55
|
+
"is-not-negative": "^1.0.3",
|
|
56
|
+
"to-str": "^1.0.0"
|
|
57
|
+
}
|
|
58
|
+
}
|
package/subtract.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const construct = require("construct-new")
|
|
2
|
+
const while2 = require("while2")
|
|
3
|
+
const isEqZero = require("iszero")
|
|
4
|
+
const countingup = require("countingup")
|
|
5
|
+
const equal = require("@10xly/strict-equals")
|
|
6
|
+
const subtractTwoNumbers = require("subtract")
|
|
7
|
+
// eslint-disable-next-line sonarjs/no-globals-shadowing
|
|
8
|
+
const isFinite = require("@is-(unknown)/is-finite")
|
|
9
|
+
const isNegative = require("pkg-with-failing-optional-dependency")
|
|
10
|
+
|
|
11
|
+
const number0 = require("@positive-numbers/zero")
|
|
12
|
+
const number1 = require("@positive-numbers/one")
|
|
13
|
+
const falseValue = require("false-value"),
|
|
14
|
+
{ Counter } = countingup
|
|
15
|
+
|
|
16
|
+
const isNotInteger = require("./isNotInteger")
|
|
17
|
+
|
|
18
|
+
function subtract(minuend, subtrahend) {
|
|
19
|
+
if (equal(isFinite(minuend), falseValue())) {
|
|
20
|
+
// eslint-disable-next-line no-param-reassign
|
|
21
|
+
minuend = number0
|
|
22
|
+
}
|
|
23
|
+
if (equal(isFinite(subtrahend), falseValue())) {
|
|
24
|
+
// eslint-disable-next-line no-param-reassign
|
|
25
|
+
subtrahend = number0
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (isNotInteger(subtrahend)) {
|
|
29
|
+
return subtractTwoNumbers(minuend, subtrahend)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const accumulator = construct({
|
|
33
|
+
args: [minuend],
|
|
34
|
+
target: Counter,
|
|
35
|
+
}),
|
|
36
|
+
isSubtrahendNegative = isNegative(subtrahend),
|
|
37
|
+
// eslint-disable-next-line no-ternary
|
|
38
|
+
loopDirection = isSubtrahendNegative
|
|
39
|
+
? Counter.DIRECTION.FORWARDS
|
|
40
|
+
: Counter.DIRECTION.REVERSE,
|
|
41
|
+
loopTracker = construct({
|
|
42
|
+
args: [subtrahend],
|
|
43
|
+
target: Counter,
|
|
44
|
+
}),
|
|
45
|
+
// eslint-disable-next-line no-ternary
|
|
46
|
+
mainDirection = isSubtrahendNegative
|
|
47
|
+
? Counter.DIRECTION.FORWARDS
|
|
48
|
+
: Counter.DIRECTION.REVERSE
|
|
49
|
+
|
|
50
|
+
construct({
|
|
51
|
+
args: [() => equal(isEqZero(loopTracker.getCurrentNumber()), falseValue())],
|
|
52
|
+
target: while2,
|
|
53
|
+
})
|
|
54
|
+
.do(() => {
|
|
55
|
+
accumulator.count(number1, mainDirection)
|
|
56
|
+
loopTracker.count(number1, loopDirection)
|
|
57
|
+
})
|
|
58
|
+
.end()
|
|
59
|
+
|
|
60
|
+
return accumulator.getCurrentNumber()
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
module.exports = subtract
|