diff --git a/AUTHORS b/AUTHORS index aacebaaeaf..dab0fffd12 100644 --- a/AUTHORS +++ b/AUTHORS @@ -278,6 +278,7 @@ kyle-compute DongKwanKho <70864292+dodokw@users.noreply.github.com> Ikem Peter Josh Kelley +Kryonn Richard Taylor NilsDietrich <61544566+NilsDietrich@users.noreply.github.com> anslem chibuike <144047596+AnslemHack@users.noreply.github.com> diff --git a/src/expression/embeddedDocs/embeddedDocs.js b/src/expression/embeddedDocs/embeddedDocs.js index 2e4383beb4..1dffe42e40 100644 --- a/src/expression/embeddedDocs/embeddedDocs.js +++ b/src/expression/embeddedDocs/embeddedDocs.js @@ -111,9 +111,11 @@ import { helpDocs } from './function/expression/help.js' import { distanceDocs } from './function/geometry/distance.js' import { intersectDocs } from './function/geometry/intersect.js' import { andDocs } from './function/logical/and.js' +import { nandDocs } from './function/logical/nand.js' import { notDocs } from './function/logical/not.js' import { nullishDocs } from './function/logical/nullish.js' import { orDocs } from './function/logical/or.js' +import { norDocs } from './function/logical/nor.js' import { xorDocs } from './function/logical/xor.js' import { mapSlicesDocs } from './function/matrix/mapSlices.js' import { columnDocs } from './function/matrix/column.js' @@ -448,9 +450,11 @@ export const embeddedDocs = { // functions - logical and: andDocs, + nand: nandDocs, not: notDocs, nullish: nullishDocs, or: orDocs, + nor: norDocs, xor: xorDocs, // functions - matrix diff --git a/src/expression/embeddedDocs/function/logical/nand.js b/src/expression/embeddedDocs/function/logical/nand.js new file mode 100644 index 0000000000..696f0d53a7 --- /dev/null +++ b/src/expression/embeddedDocs/function/logical/nand.js @@ -0,0 +1,17 @@ +export const nandDocs = { + name: 'nand', + category: 'Logical', + syntax: [ + 'x nand y', + 'nand(x, y)' + ], + description: 'Logical nand. Test whether at least one of values is zero.', + examples: [ + 'nand(true, false)', + 'nand(true, true)', + 'nand(2, 4)' + ], + seealso: [ + 'not', 'or', 'xor' + ] +} diff --git a/src/expression/embeddedDocs/function/logical/nor.js b/src/expression/embeddedDocs/function/logical/nor.js new file mode 100644 index 0000000000..cb21a77d2b --- /dev/null +++ b/src/expression/embeddedDocs/function/logical/nor.js @@ -0,0 +1,17 @@ +export const norDocs = { + name: 'nor', + category: 'Logical', + syntax: [ + 'x nor y', + 'nor(x, y)' + ], + description: 'Logical nor. Test if both values are zero', + examples: [ + 'nor(true, false)', + 'nor(false, false)', + 'nor(0, 4)' + ], + seealso: [ + 'not', 'or', 'xor' + ] +} diff --git a/src/expression/operators.js b/src/expression/operators.js index 8076f70aeb..97622ae9e6 100644 --- a/src/expression/operators.js +++ b/src/expression/operators.js @@ -38,6 +38,12 @@ export const properties = [ op: 'or', associativity: 'left', associativeWith: [] + }, + // logical nand + 'OperatorNode:nand': { + op: 'nand', + associativity: 'left', + associativeWith: [] } }, { // logical xor @@ -52,6 +58,12 @@ export const properties = [ op: 'and', associativity: 'left', associativeWith: [] + }, + // logical nor + 'OperatorNode:nor': { + op: 'nor', + associativity: 'left', + associativeWith: [] } }, { // bitwise or diff --git a/src/expression/parse.js b/src/expression/parse.js index 7be4f883ee..9bf072924f 100644 --- a/src/expression/parse.js +++ b/src/expression/parse.js @@ -174,7 +174,9 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({ and: true, xor: true, or: true, - not: true + nand: true, + not: true, + nor: true } const CONSTANTS = { @@ -735,7 +737,7 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({ * @private */ function parseConditional (state) { - let node = parseLogicalOr(state) + let node = parseLogicalOrNand(state) while (state.token === '?') { // eslint-disable-line no-unmodified-loop-condition // set a conditional level, the range operator will be ignored as long @@ -765,15 +767,17 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({ /** * logical or, 'x or y' + * logical nand, 'x nand y' * @return {Node} node * @private */ - function parseLogicalOr (state) { + function parseLogicalOrNand (state) { let node = parseLogicalXor(state) - while (state.token === 'or') { // eslint-disable-line no-unmodified-loop-condition + while (state.token === 'or' || state.token === 'nand') { // eslint-disable-line no-unmodified-loop-condition + const op = state.token getTokenSkipNewline(state) - node = new OperatorNode('or', 'or', [node, parseLogicalXor(state)]) + node = new OperatorNode(op, op, [node, parseLogicalXor(state)]) } return node @@ -785,11 +789,11 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({ * @private */ function parseLogicalXor (state) { - let node = parseLogicalAnd(state) + let node = parseLogicalAndNor(state) while (state.token === 'xor') { // eslint-disable-line no-unmodified-loop-condition getTokenSkipNewline(state) - node = new OperatorNode('xor', 'xor', [node, parseLogicalAnd(state)]) + node = new OperatorNode('xor', 'xor', [node, parseLogicalAndNor(state)]) } return node @@ -797,15 +801,17 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({ /** * logical and, 'x and y' + * logical nor, 'x nor y' * @return {Node} node * @private */ - function parseLogicalAnd (state) { + function parseLogicalAndNor (state) { let node = parseBitwiseOr(state) - while (state.token === 'and') { // eslint-disable-line no-unmodified-loop-condition + while (state.token === 'and' || state.token === 'nor') { // eslint-disable-line no-unmodified-loop-condition + const op = state.token getTokenSkipNewline(state) - node = new OperatorNode('and', 'and', [node, parseBitwiseOr(state)]) + node = new OperatorNode(op, op, [node, parseBitwiseOr(state)]) } return node diff --git a/src/factoriesAny.js b/src/factoriesAny.js index 15ea5de0d0..d8b50a459d 100644 --- a/src/factoriesAny.js +++ b/src/factoriesAny.js @@ -70,6 +70,8 @@ export { createRe } from './function/complex/re.js' export { createNot } from './function/logical/not.js' export { createNullish } from './function/logical/nullish.js' export { createOr } from './function/logical/or.js' +export { createNor } from './function/logical/nor.js' +export { createNand } from './function/logical/nand.js' export { createXor } from './function/logical/xor.js' export { createConcat } from './function/matrix/concat.js' export { createColumn } from './function/matrix/column.js' diff --git a/src/factoriesNumber.js b/src/factoriesNumber.js index 73a0eaafb5..b93f328e8d 100644 --- a/src/factoriesNumber.js +++ b/src/factoriesNumber.js @@ -48,9 +48,11 @@ import { modNumber, multiplyNumber, normNumber, + norNumber, notNumber, nthRootNumber, orNumber, + nandNumber, powNumber, rightArithShiftNumber, rightLogShiftNumber, @@ -204,9 +206,11 @@ export { createParserClass } from './expression/Parser.js' // logical export const createAnd = /* #__PURE__ */ createNumberFactory('and', andNumber) +export const createNand = /* #__PURE__ */ createNumberFactory('nand', nandNumber) export const createNot = /* #__PURE__ */ createNumberFactory('not', notNumber) export const createOr = /* #__PURE__ */ createNumberFactory('or', orNumber) export const createXor = /* #__PURE__ */ createNumberFactory('xor', xorNumber) +export const createNor = /* #__PURE__ */ createNumberFactory('nor', norNumber) // matrix export { createMapSlices } from './function/matrix/mapSlices.js' diff --git a/src/function/logical/nand.js b/src/function/logical/nand.js new file mode 100644 index 0000000000..9eb5ac1e36 --- /dev/null +++ b/src/function/logical/nand.js @@ -0,0 +1,51 @@ +import { factory } from '../../utils/factory.js' +import { nandNumber } from '../../plain/number/logical.js' + +const name = 'nand' +const dependencies = [ + 'typed', + 'and', + 'not' +] + +export const createNand = /* #__PURE__ */ factory(name, dependencies, ({ typed, and, not }) => { + /** + * Logical `nand`. Test if at least one of the inputs is zero. + * For matrices, the function is evaluated element wise. + * + * Syntax: + * + * math.nand(x, y) + * + * Examples: + * + * math.nand(2, 4) // returns false + * + * a = [2, 5, 0] + * b = [0, 22, 0] + * c = 0 + * + * math.nand(a, b) // returns [true, false, true] + * math.nand(b, c) // returns [true, true, true] + * + * See also: + * + * and, or, not, xor + * + * @param {number | BigNumber | bigint | Complex | Unit | Array | Matrix} x First value to check + * @param {number | BigNumber | bigint | Complex | Unit | Array | Matrix} y Second value to check + * @return {boolean | Array | Matrix} + * Returns true when at least one of the inputs is zero + */ + return typed( + name, + { + 'number, number': nandNumber, + 'bigint, bigint': nandNumber, + + 'any, any': function (x, y) { + return not(and(x, y)) + } + } + ) +}) diff --git a/src/function/logical/nor.js b/src/function/logical/nor.js new file mode 100644 index 0000000000..ed2e913d9c --- /dev/null +++ b/src/function/logical/nor.js @@ -0,0 +1,51 @@ +import { factory } from '../../utils/factory.js' +import { norNumber } from '../../plain/number/logical.js' + +const name = 'nor' +const dependencies = [ + 'typed', + 'or', + 'not' +] + +export const createNor = /* #__PURE__ */ factory(name, dependencies, ({ typed, or, not }) => { + /** + * Logical `nor`. Test if both of values are defined with zero. + * For matrices, the function is evaluated element wise. + * + * Syntax: + * + * math.nor(x, y) + * + * Examples: + * + * math.nor(2, 4) // returns false + * + * a = [2, 5, 0] + * b = [0, 22, 0] + * c = 0 + * + * math.nor(a, b) // returns [false, false, true] + * math.nor(b, c) // returns [true, false, true] + * + * See also: + * + * and, or, not, xor + * + * @param {number | BigNumber | bigint | Complex | Unit | Array | Matrix} x First value to check + * @param {number | BigNumber | bigint | Complex | Unit | Array | Matrix} y Second value to check + * @return {boolean | Array | Matrix} + * Returns true when both inputs are zero + */ + return typed( + name, + { + 'number, number': norNumber, + 'bigint, bigint': norNumber, + + 'any, any': function (x, y) { + return not(or(x, y)) + } + } + ) +}) diff --git a/src/plain/number/logical.js b/src/plain/number/logical.js index cb3dc7e3a6..d14c75ab9c 100644 --- a/src/plain/number/logical.js +++ b/src/plain/number/logical.js @@ -11,6 +11,11 @@ export function orNumber (x, y) { } orNumber.signature = n2 +export function norNumber (x, y) { + return !(x || y) +} +norNumber.signature = n2 + export function xorNumber (x, y) { return !!x !== !!y } @@ -20,3 +25,8 @@ export function andNumber (x, y) { return !!(x && y) } andNumber.signature = n2 + +export function nandNumber (x, y) { + return !(x && y) +} +nandNumber.signature = n2 diff --git a/src/utils/latex.js b/src/utils/latex.js index 6ae2dc3b43..8737397fb6 100644 --- a/src/utils/latex.js +++ b/src/utils/latex.js @@ -105,8 +105,10 @@ export const latexOperators = { bitXor: '\\underline{|}', bitOr: '|', and: '\\wedge', + nand: '\\uparrow', xor: '\\veebar', - or: '\\vee' + or: '\\vee', + nor: '\\downarrow' } export const latexFunctions = { @@ -179,8 +181,10 @@ export const latexFunctions = { // logical and: { 2: `\\left(\${args[0]}${latexOperators.and}\${args[1]}\\right)` }, + nand: { 2: `\\left(\${args[0]}${latexOperators.nand}\${args[1]}\\right)` }, not: { 1: latexOperators.not + '\\left(${args[0]}\\right)' }, or: { 2: `\\left(\${args[0]}${latexOperators.or}\${args[1]}\\right)` }, + nor: { 2: `\\left(\${args[0]}${latexOperators.nor}\${args[1]}\\right)` }, xor: { 2: `\\left(\${args[0]}${latexOperators.xor}\${args[1]}\\right)` }, // matrix diff --git a/test/typescript-tests/testTypes.ts b/test/typescript-tests/testTypes.ts index 4b38e7710c..031cd89a17 100644 --- a/test/typescript-tests/testTypes.ts +++ b/test/typescript-tests/testTypes.ts @@ -3181,3 +3181,99 @@ Match types of exact positional arguments. expectTypeOf(mixArray3).toMatchTypeOf>() expectTypeOf(unitArray3).toMatchTypeOf>() } + +/** + * NAND examples + */ +{ + const math = create(all, {}) + + // number input + assert.strictEqual(math.nand(3, 2), false) + assert.strictEqual(math.nand(3, 0), true) + assert.strictEqual(math.nand(0, 2), true) + assert.strictEqual(math.nand(0, 0), true) + + // bignumber input + assert.deepStrictEqual(math.nand(math.bignumber(4), math.bignumber(2)), false) + assert.deepStrictEqual(math.nand(math.bignumber(3), 0), true) + assert.deepStrictEqual(math.nand(math.bignumber(0), math.bignumber(0)), true) + + // Complex input + const a = math.complex(3.24, -2.71) + const b = math.complex(0, 0) + assert.deepStrictEqual(math.nand(a, a), false) + assert.deepStrictEqual(math.nand(a, b), true) + assert.deepStrictEqual(math.nand(b, b), true) + + // unit input + const u1 = math.unit(3.2, 'cm') + const u2 = math.unit('cm') + const u3 = math.unit(5.51, 'cm') + assert.deepStrictEqual(math.nand(u1, u2), true) + assert.deepStrictEqual(math.nand(u1, u3), false) + + // array input + assert.deepStrictEqual(math.nand([3.2, 3.8, -4.7], 2), [false, false, false]) + assert.deepStrictEqual(math.nand([3.2, 3.8, -4.7], 0), [true, true, true]) + assert.deepStrictEqual(math.nand([3.2, 3.8, 0], 7), [false, false, true]) + assert.deepStrictEqual(math.nand([3.21, 3.82, -4.71], math.bignumber(1)), [ + false, + false, + false + ]) + + // matrix of decimals + assert.deepStrictEqual( + math.nand(math.matrix([1, 4, 0, 0]), math.matrix([1, 0, 6, 0])).valueOf(), + [false, true, true, true] + ) +} + +/** + * NOR examples + */ +{ + const math = create(all, {}) + + // number input + assert.strictEqual(math.nor(3, 2), false) + assert.strictEqual(math.nor(3, 0), false) + assert.strictEqual(math.nor(0, 2), false) + assert.strictEqual(math.nor(0, 0), true) + + // bignumber input + assert.deepStrictEqual(math.nor(math.bignumber(4), math.bignumber(2)), false) + assert.deepStrictEqual(math.nor(math.bignumber(3), 0), false) + assert.deepStrictEqual(math.nor(math.bignumber(0), math.bignumber(0)), true) + + // Complex input + const a = math.complex(3.24, -2.71) + const b = math.complex(0, 0) + assert.deepStrictEqual(math.nor(a, a), false) + assert.deepStrictEqual(math.nor(a, b), false) + assert.deepStrictEqual(math.nor(b, b), true) + + // unit input + const u1 = math.unit(3.2, 'cm') + const u2 = math.unit('cm') + const u3 = math.unit(5.51, 'cm') + assert.deepStrictEqual(math.nor(u1, u2), false) + assert.deepStrictEqual(math.nor(u1, u3), false) + + // array input + assert.deepStrictEqual(math.nor([3.2, 3.8, -4.7], 2), [false, false, false]) + assert.deepStrictEqual(math.nor([3.2, 3.8, 0], 0), [false, false, true]) + assert.deepStrictEqual(math.nor([3.2, 3.8, 0], 7), [false, false, false]) + assert.deepStrictEqual(math.nor([3.21, 3.82, -4.71], math.bignumber(1)), [ + false, + false, + false + ]) + + // matrix of decimals + assert.deepStrictEqual( + math.nor(math.matrix([1, 4, 0, 0]), math.matrix([1, 0, 6, 0])).valueOf(), + [false, false, false, true] + ) +} diff --git a/test/unit-tests/expression/parse.test.js b/test/unit-tests/expression/parse.test.js index 444247244f..ee14f57dd4 100644 --- a/test/unit-tests/expression/parse.test.js +++ b/test/unit-tests/expression/parse.test.js @@ -1256,7 +1256,7 @@ describe('parse', function () { }) it('should create an object with unquoted keys that are keywords', function () { - assert.deepStrictEqual(parseAndEval('{ mod: 1, and: 1, not: 1, or: 1, xor: 1, to: 1, in: 1 }'), { mod: 1, and: 1, not: 1, or: 1, xor: 1, to: 1, in: 1 }) + assert.deepStrictEqual(parseAndEval('{ mod: 1, and: 1, not: 1, or: 1, xor: 1, to: 1, in: 1, nor: 1, nand: 1 }'), { mod: 1, and: 1, not: 1, or: 1, xor: 1, to: 1, in: 1, nor: 1, nand: 1 }) }) it('should create an object with child object', function () { @@ -1979,6 +1979,24 @@ describe('parse', function () { assert.strictEqual(scope.a, false) }) + it('should parse logical nand', function () { + assert.strictEqual(parseAndEval('2 nand 6'), false) + assert.strictEqual(parseAndEval('2 nand 0'), true) + assert.strictEqual(parseAndEval('true nand true'), false) + assert.strictEqual(parseAndEval('true nand false'), true) + assert.strictEqual(parseAndEval('false nand true'), true) + assert.strictEqual(parseAndEval('false nand false'), true) + assert.throws(function () { parseAndEval('true nand undefined') }, TypeError) + }) + + it('should parse logical nand inside a function definition', function () { + const scope = {} + const f = parseAndEval('f(x) = x > 2 nand x < 4', scope) + assert.strictEqual(f(1), true) + assert.strictEqual(f(3), false) + assert.strictEqual(f(5), true) + }) + it('should always pass a Map as scope to a rawArgs function', function () { const myMath = math.create() function myFunction (args, _math, _scope) { @@ -2040,6 +2058,24 @@ describe('parse', function () { assert.deepStrictEqual(scope, { a: true }) }) + it('should parse logical nor', function () { + assert.strictEqual(parseAndEval('2 nor 6'), false) + assert.strictEqual(parseAndEval('2 nor 0'), false) + assert.strictEqual(parseAndEval('true nor true'), false) + assert.strictEqual(parseAndEval('true nor false'), false) + assert.strictEqual(parseAndEval('false nor true'), false) + assert.strictEqual(parseAndEval('false nor false'), true) + assert.throws(function () { parseAndEval('false nor undefined') }, TypeError) + }) + + it('should parse logical nor inside a function definition', function () { + const scope = {} + const f = parseAndEval('f(x) = x < 2 nor x > 4', scope) + assert.strictEqual(f(1), false) + assert.strictEqual(f(3), true) + assert.strictEqual(f(5), false) + }) + it('should parse logical not', function () { assert.strictEqual(parseAndEval('not 2'), false) assert.strictEqual(parseAndEval('not not 2'), true) @@ -2355,6 +2391,7 @@ describe('parse', function () { assert.strictEqual(parseAndEval('2 > 3 ? true : false'), false) assert.strictEqual(parseAndEval('2 == 3 ? true : false'), false) assert.strictEqual(parseAndEval('3 ? 2 + 4 : 2 - 1'), 6) + assert.strictEqual(parseAndEval('true ? false : false nand true'), false) assert.deepStrictEqual(parseAndEval('3 ? true : false; 22'), new ResultSet([22])) assert.deepStrictEqual(parseAndEval('3 ? 5cm to m : 5cm in mm'), new Unit(5, 'cm').to('m')) assert.deepStrictEqual(parseAndEval('2 == 4-2 ? [1,2] : false'), math.matrix([1, 2])) @@ -2379,6 +2416,10 @@ describe('parse', function () { assert.strictEqual(parseAndEval('4 and 2 | 2'), true) }) + it('should respect precedence between bitwise or | and logical nand', function () { + assert.strictEqual(parseAndEval('true nand true | true'), false) + }) + it('should respect precedence between bitwise xor ^| and bitwise or |', function () { assert.strictEqual(parseAndEval('4 ^| 6 | 2'), 2) assert.strictEqual(parseAndEval('2 | 4 ^| 6'), 2) @@ -2398,6 +2439,21 @@ describe('parse', function () { assert.strictEqual(parseAndEval('(true or true) and false'), false) }) + it('should respect precedence between logical nand and or', function () { + assert.strictEqual(parseAndEval('true nand false or true'), true) + assert.strictEqual(parseAndEval('false or true nand true'), false) + }) + + it('should respect precedence between logical nand and and', function () { + assert.strictEqual(parseAndEval('true nand true and false'), true) + assert.strictEqual(parseAndEval('true nand false and false'), true) + }) + + it('should respect precedence between logical nand and xor', function () { + assert.strictEqual(parseAndEval('false nand false xor true'), true) + assert.strictEqual(parseAndEval('false nand true xor true'), true) + }) + it('should respect precedence of conditional operator and logical or', function () { const node = math.parse('1 or 0 ? 2 or 3 : 0 or 0') assert(node instanceof ConditionalNode) @@ -2407,6 +2463,34 @@ describe('parse', function () { assert.strictEqual(node.compile().evaluate(), true) }) + it('should respect precedence between logical nor and or', function () { + assert.strictEqual(parseAndEval('true or false nor true'), true) + assert.strictEqual(parseAndEval('true or true nor false'), true) + }) + + it('should respect precedence between logical nor and bitwise or |', function () { + assert.strictEqual(parseAndEval('true nor false | true'), false) + assert.strictEqual(parseAndEval('false nor false | true'), false) + }) + + it('should respect precedence between logical nor and and', function () { + assert.strictEqual(parseAndEval('false nor true and false'), false) + assert.strictEqual(parseAndEval('true and false nor false'), true) + }) + + it('should respect precedence between logical nor and xor', function () { + assert.strictEqual(parseAndEval('false xor false nor true'), false) + }) + + it('should respect precedence of conditional operator and logical nor', function () { + const node = math.parse('1 nor 0 ? 2 nor 3 : 0 nor 0') + assert(node instanceof ConditionalNode) + assert.strictEqual(node.condition.toString(), '1 nor 0') + assert.strictEqual(node.trueExpr.toString(), '2 nor 3') + assert.strictEqual(node.falseExpr.toString(), '0 nor 0') + assert.strictEqual(node.compile().evaluate(), true) + }) + it('should respect precedence of conditional operator and relational operators', function () { const node = math.parse('a == b ? a > b : a < b') assert(node instanceof ConditionalNode) @@ -2749,6 +2833,7 @@ describe('parse', function () { assert.strictEqual(parse('false and true').toString(), 'false and true') assert.strictEqual(parse('false xor true').toString(), 'false xor true') assert.strictEqual(parse('false or true').toString(), 'false or true') + assert.strictEqual(parse('false nor true').toString(), 'false nor true') assert.strictEqual(parse('not true').toString(), 'not true') assert.strictEqual(parse('5!').toString(), '5!') }) diff --git a/test/unit-tests/function/logical/nand.test.js b/test/unit-tests/function/logical/nand.test.js new file mode 100644 index 0000000000..17c9167d24 --- /dev/null +++ b/test/unit-tests/function/logical/nand.test.js @@ -0,0 +1,210 @@ +// test nand +import assert from 'assert' + +import math from '../../../../src/defaultInstance.js' +const bignumber = math.bignumber +const complex = math.complex +const matrix = math.matrix +const sparse = math.sparse +const unit = math.unit +const nand = math.nand + +describe('nand', function () { + it('should nand two numbers correctly', function () { + assert.strictEqual(nand(1, 1), false) + assert.strictEqual(nand(-1, 1), false) + assert.strictEqual(nand(-1, -1), false) + assert.strictEqual(nand(0, -1), true) + assert.strictEqual(nand(1, 0), true) + assert.strictEqual(nand(1, NaN), true) + assert.strictEqual(nand(NaN, 1), true) + assert.strictEqual(nand(1e10, 0.019209), false) + assert.strictEqual(nand(-1.0e-100, 1.0e-100), false) + assert.strictEqual(nand(Infinity, -Infinity), false) + }) + + it('should nand two complex numbers', function () { + assert.strictEqual(nand(complex(1, 1), complex(1, 1)), false) + assert.strictEqual(nand(complex(0, 1), complex(1, 1)), false) + assert.strictEqual(nand(complex(1, 0), complex(1, 1)), false) + assert.strictEqual(nand(complex(1, 1), complex(0, 1)), false) + assert.strictEqual(nand(complex(1, 1), complex(1, 0)), false) + assert.strictEqual(nand(complex(1, 0), complex(1, 0)), false) + assert.strictEqual(nand(complex(0, 1), complex(0, 1)), false) + assert.strictEqual(nand(complex(0, 0), complex(1, 1)), true) + assert.strictEqual(nand(complex(0, 0), complex(0, 1)), true) + assert.strictEqual(nand(complex(0, 0), complex(1, 0)), true) + assert.strictEqual(nand(complex(1, 1), complex(0, 0)), true) + assert.strictEqual(nand(complex(0, 1), complex(0, 0)), true) + assert.strictEqual(nand(complex(1, 0), complex(0, 0)), true) + assert.strictEqual(nand(complex(), complex(1, 1)), true) + assert.strictEqual(nand(complex(0), complex(1, 1)), true) + assert.strictEqual(nand(complex(1), complex(1, 1)), false) + assert.strictEqual(nand(complex(1, 1), complex()), true) + assert.strictEqual(nand(complex(1, 1), complex(0)), true) + assert.strictEqual(nand(complex(1, 1), complex(1)), false) + }) + + it('should nand mixed numbers nand complex numbers', function () { + assert.strictEqual(nand(complex(1, 1), 1), false) + assert.strictEqual(nand(complex(1, 1), 0), true) + assert.strictEqual(nand(1, complex(1, 1)), false) + assert.strictEqual(nand(0, complex(1, 1)), true) + assert.strictEqual(nand(complex(0, 0), 1), true) + assert.strictEqual(nand(1, complex(0, 0)), true) + }) + + it('should nand two booleans', function () { + assert.strictEqual(nand(true, true), false) + assert.strictEqual(nand(true, false), true) + assert.strictEqual(nand(false, true), true) + assert.strictEqual(nand(false, false), true) + }) + + it('should nand mixed numbers nand booleans', function () { + assert.strictEqual(nand(2, true), false) + assert.strictEqual(nand(2, false), true) + assert.strictEqual(nand(0, true), true) + assert.strictEqual(nand(true, 2), false) + assert.strictEqual(nand(false, 2), true) + }) + + it('should nand bignumbers', function () { + assert.strictEqual(nand(bignumber(1), bignumber(1)), false) + assert.strictEqual(nand(bignumber(-1), bignumber(1)), false) + assert.strictEqual(nand(bignumber(-1), bignumber(-1)), false) + assert.strictEqual(nand(bignumber(0), bignumber(-1)), true) + assert.strictEqual(nand(bignumber(1), bignumber(0)), true) + assert.strictEqual(nand(bignumber(1), bignumber(NaN)), true) + assert.strictEqual(nand(bignumber(NaN), bignumber(1)), true) + assert.strictEqual(nand(bignumber('1e+10'), bignumber(0.19209)), false) + assert.strictEqual(nand(bignumber('-1.0e-100'), bignumber('1.0e-100')), false) + assert.strictEqual(nand(bignumber(Infinity), bignumber(-Infinity)), false) + }) + + it('should nand bigints', function () { + assert.strictEqual(nand(1n, 1n), false) + assert.strictEqual(nand(-1n, 1n), false) + assert.strictEqual(nand(-1n, -1n), false) + assert.strictEqual(nand(0n, -1n), true) + assert.strictEqual(nand(1n, 0n), true) + }) + + it('should nand mixed numbers nand bignumbers', function () { + assert.strictEqual(nand(bignumber(2), 3), false) + assert.strictEqual(nand(2, bignumber(2)), false) + assert.strictEqual(nand(0, bignumber(2)), true) + assert.strictEqual(nand(2, bignumber(0)), true) + assert.strictEqual(nand(bignumber(0), 2), true) + assert.strictEqual(nand(bignumber(2), 0), true) + }) + + it('should nand mixed numbers nand bigints', function () { + assert.strictEqual(nand(2n, 3), false) + assert.strictEqual(nand(2, 2n), false) + assert.strictEqual(nand(0, 2n), true) + assert.strictEqual(nand(2, 0n), true) + assert.strictEqual(nand(0n, 2), true) + assert.strictEqual(nand(2n, 0), true) + }) + + it('should nand two units', function () { + assert.strictEqual(nand(unit('100cm'), unit('10inch')), false) + assert.strictEqual(nand(unit('100cm'), unit('0 inch')), true) + assert.strictEqual(nand(unit('0cm'), unit('1m')), true) + assert.strictEqual(nand(unit('m'), unit('1m')), true) + assert.strictEqual(nand(unit('1dm'), unit('m')), true) + assert.strictEqual(nand(unit('-100cm'), unit('-10inch')), false) + assert.strictEqual(nand(unit(5, 'km'), unit(100, 'gram')), false) + assert.strictEqual(nand(unit(5, 'km'), unit(0, 'gram')), true) + assert.strictEqual(nand(unit(0, 'km'), unit(100, 'gram')), true) + + assert.strictEqual(nand(unit(bignumber(0), 'm'), unit(bignumber(0), 'm')), true) + assert.strictEqual(nand(unit(bignumber(1), 'm'), unit(bignumber(0), 'm')), true) + assert.strictEqual(nand(unit(bignumber(0), 'm'), unit(bignumber(1), 'm')), true) + assert.strictEqual(nand(unit(bignumber(1), 'm'), unit(bignumber(1), 'm')), false) + }) + + describe('Array', function () { + it('should nand array - scalar', function () { + assert.deepStrictEqual(nand(10, [0, 2]), [true, false]) + assert.deepStrictEqual(nand([0, 2], 10), [true, false]) + }) + + it('should nand array - array', function () { + assert.deepStrictEqual(nand([0, 1, 0, 12], [0, 0, 1, 22]), [true, true, true, false]) + assert.deepStrictEqual(nand([], []), []) + }) + + it('should nand broadcastable arrays', function () { + assert.deepStrictEqual(nand([[0, 1, 0, 12]], [[0], [0], [1], [22]]), [[true, true, true, true], [true, true, true, true], [true, false, true, false], [true, false, true, false]]) + }) + + it('should nand array - dense matrix', function () { + assert.deepStrictEqual(nand([0, 1, 0, 12], matrix([0, 0, 1, 22])), matrix([true, true, true, false])) + assert.deepStrictEqual(nand([], matrix([])), matrix([])) + }) + + it('should nand array - sparse matrix', function () { + assert.deepStrictEqual(nand([[0, 1], [0, 12]], sparse([[0, 0], [1, 22]])), sparse([[true, true], [true, false]])) + }) + }) + + describe('DenseMatrix', function () { + it('should nand dense matrix - scalar', function () { + assert.deepStrictEqual(nand(10, matrix([0, 2])), matrix([true, false])) + assert.deepStrictEqual(nand(matrix([0, 2]), 10), matrix([true, false])) + }) + + it('should nand dense matrix - array', function () { + assert.deepStrictEqual(nand(matrix([0, 1, 0, 12]), [0, 0, 1, 22]), matrix([true, true, true, false])) + assert.deepStrictEqual(nand(matrix([]), []), matrix([])) + }) + + it('should nand dense matrix - dense matrix', function () { + assert.deepStrictEqual(nand(matrix([0, 1, 0, 12]), matrix([0, 0, 1, 22])), matrix([true, true, true, false])) + assert.deepStrictEqual(nand(matrix([]), matrix([])), matrix([])) + }) + + it('should nand dense matrix - sparse matrix', function () { + assert.deepStrictEqual(nand(matrix([[0, 1], [0, 12]]), sparse([[0, 0], [1, 22]])), sparse([[true, true], [true, false]])) + }) + }) + + describe('SparseMatrix', function () { + it('should nand sparse matrix - scalar', function () { + assert.deepStrictEqual(nand(10, sparse([[0], [2]])), sparse([[true], [false]])) + assert.deepStrictEqual(nand(sparse([[0], [2]]), 10), sparse([[true], [false]])) + }) + + it('should nand sparse matrix - array', function () { + assert.deepStrictEqual(nand(sparse([[0, 1], [0, 12]]), [[0, 0], [1, 22]]), sparse([[true, true], [true, false]])) + }) + + it('should nand sparse matrix - dense matrix', function () { + assert.deepStrictEqual(nand(sparse([[0, 1], [0, 12]]), matrix([[0, 0], [1, 22]])), sparse([[true, true], [true, false]])) + }) + + it('should nand sparse matrix - sparse matrix', function () { + assert.deepStrictEqual(nand(sparse([[0, 1], [0, 12]]), sparse([[0, 0], [1, 22]])), sparse([[true, true], [true, false]])) + }) + }) + + it('should throw an error in case of invalid number of arguments', function () { + assert.throws(function () { nand(1) }, /TypeError: Too few arguments/) + assert.throws(function () { nand(1, 2, 3) }, /TypeError: Too many arguments/) + }) + + it('should throw an error in case of invalid type of arguments', function () { + assert.throws(function () { nand(2, null) }, /TypeError: Unexpected type of argument/) + assert.throws(function () { nand(new Date(), false) }, /TypeError: Unexpected type of argument/) + assert.throws(function () { nand(false, new Date()) }, /TypeError: Unexpected type of argument/) + assert.throws(function () { nand(false, undefined) }, /TypeError: Unexpected type of argument/) + assert.throws(function () { nand(undefined, false) }, /TypeError: Unexpected type of argument/) + }) + + it('should LaTeX nand', function () { + const expression = math.parse('nand(1,2)') + assert.strictEqual(expression.toTex(), '\\left(1\\uparrow2\\right)') + }) +}) diff --git a/test/unit-tests/function/logical/nor.test.js b/test/unit-tests/function/logical/nor.test.js new file mode 100644 index 0000000000..75ea75c793 --- /dev/null +++ b/test/unit-tests/function/logical/nor.test.js @@ -0,0 +1,236 @@ +// test nor +import assert from 'assert' + +import math from '../../../../src/defaultInstance.js' +const bignumber = math.bignumber +const complex = math.complex +const matrix = math.matrix +const sparse = math.sparse +const unit = math.unit +const nor = math.nor + +describe('nor', function () { + it('should nor two numbers correctly', function () { + assert.strictEqual(nor(1, 1), false) + assert.strictEqual(nor(-1, 1), false) + assert.strictEqual(nor(-1, -1), false) + assert.strictEqual(nor(0, -1), false) + assert.strictEqual(nor(1, 0), false) + assert.strictEqual(nor(1, NaN), false) + assert.strictEqual(nor(NaN, 1), false) + assert.strictEqual(nor(1e10, 0.019209), false) + assert.strictEqual(nor(-1.0e-100, 1.0e-100), false) + assert.strictEqual(nor(Infinity, -Infinity), false) + assert.strictEqual(nor(NaN, NaN), true) + assert.strictEqual(nor(NaN, 0), true) + assert.strictEqual(nor(0, NaN), true) + assert.strictEqual(nor(0, 0), true) + }) + + it('should nor two complex numbers', function () { + assert.strictEqual(nor(complex(1, 1), complex(1, 1)), false) + assert.strictEqual(nor(complex(0, 1), complex(1, 1)), false) + assert.strictEqual(nor(complex(1, 0), complex(1, 1)), false) + assert.strictEqual(nor(complex(1, 1), complex(0, 1)), false) + assert.strictEqual(nor(complex(1, 1), complex(1, 0)), false) + assert.strictEqual(nor(complex(1, 0), complex(1, 0)), false) + assert.strictEqual(nor(complex(0, 1), complex(0, 1)), false) + assert.strictEqual(nor(complex(0, 0), complex(1, 1)), false) + assert.strictEqual(nor(complex(0, 0), complex(0, 1)), false) + assert.strictEqual(nor(complex(0, 0), complex(1, 0)), false) + assert.strictEqual(nor(complex(1, 1), complex(0, 0)), false) + assert.strictEqual(nor(complex(0, 1), complex(0, 0)), false) + assert.strictEqual(nor(complex(1, 0), complex(0, 0)), false) + assert.strictEqual(nor(complex(), complex(1, 1)), false) + assert.strictEqual(nor(complex(0), complex(1, 1)), false) + assert.strictEqual(nor(complex(1), complex(1, 1)), false) + assert.strictEqual(nor(complex(1, 1), complex()), false) + assert.strictEqual(nor(complex(1, 1), complex(0)), false) + assert.strictEqual(nor(complex(1, 1), complex(1)), false) + assert.strictEqual(nor(complex(0, 0), complex(0, 0)), true) + assert.strictEqual(nor(complex(), complex()), true) + }) + + it('should nor mixed numbers and complex numbers', function () { + assert.strictEqual(nor(complex(1, 1), 1), false) + assert.strictEqual(nor(complex(1, 1), 0), false) + assert.strictEqual(nor(1, complex(1, 1)), false) + assert.strictEqual(nor(0, complex(1, 1)), false) + assert.strictEqual(nor(complex(0, 0), 1), false) + assert.strictEqual(nor(1, complex(0, 0)), false) + assert.strictEqual(nor(0, complex(0, 0)), true) + assert.strictEqual(nor(complex(0, 0), 0), true) + }) + + it('should nor two booleans', function () { + assert.strictEqual(nor(true, true), false) + assert.strictEqual(nor(true, false), false) + assert.strictEqual(nor(false, true), false) + assert.strictEqual(nor(false, false), true) + }) + + it('should nor mixed numbers and booleans', function () { + assert.strictEqual(nor(2, true), false) + assert.strictEqual(nor(2, false), false) + assert.strictEqual(nor(0, true), false) + assert.strictEqual(nor(0, false), true) + assert.strictEqual(nor(true, 2), false) + assert.strictEqual(nor(false, 2), false) + assert.strictEqual(nor(false, 0), true) + }) + + it('should nor bignumbers', function () { + assert.strictEqual(nor(bignumber(1), bignumber(1)), false) + assert.strictEqual(nor(bignumber(-1), bignumber(1)), false) + assert.strictEqual(nor(bignumber(-1), bignumber(-1)), false) + assert.strictEqual(nor(bignumber(0), bignumber(-1)), false) + assert.strictEqual(nor(bignumber(1), bignumber(0)), false) + assert.strictEqual(nor(bignumber(1), bignumber(NaN)), false) + assert.strictEqual(nor(bignumber(NaN), bignumber(1)), false) + assert.strictEqual(nor(bignumber('1e+10'), bignumber(0.19209)), false) + assert.strictEqual(nor(bignumber('-1.0e-100'), bignumber('1.0e-100')), false) + assert.strictEqual(nor(bignumber(Infinity), bignumber(-Infinity)), false) + assert.strictEqual(nor(bignumber(NaN), bignumber(NaN)), true) + assert.strictEqual(nor(bignumber(NaN), bignumber(0)), true) + assert.strictEqual(nor(bignumber(0), bignumber(NaN)), true) + assert.strictEqual(nor(bignumber(0), bignumber(0)), true) + }) + + it('should nor bigints', function () { + assert.strictEqual(nor(1n, 1n), false) + assert.strictEqual(nor(-1n, 1n), false) + assert.strictEqual(nor(-1n, -1n), false) + assert.strictEqual(nor(0n, -1n), false) + assert.strictEqual(nor(1n, 0n), false) + }) + + it('should nor mixed numbers and bignumbers', function () { + assert.strictEqual(nor(bignumber(2), 3), false) + assert.strictEqual(nor(2, bignumber(2)), false) + assert.strictEqual(nor(0, bignumber(2)), false) + assert.strictEqual(nor(2, bignumber(0)), false) + assert.strictEqual(nor(bignumber(0), 2), false) + assert.strictEqual(nor(bignumber(0), 0), true) + assert.strictEqual(nor(bignumber(2), 0), false) + assert.strictEqual(nor(bignumber(0), 0), true) + }) + + it('should nor mixed numbers and bigints', function () { + assert.strictEqual(nor(2n, 3), false) + assert.strictEqual(nor(2, 3n), false) + }) + + it('should nor two units', function () { + assert.strictEqual(nor(unit('100cm'), unit('10inch')), false) + assert.strictEqual(nor(unit('100cm'), unit('0 inch')), false) + assert.strictEqual(nor(unit('0cm'), unit('1m')), false) + assert.strictEqual(nor(unit('m'), unit('1m')), false) + assert.strictEqual(nor(unit('1dm'), unit('m')), false) + assert.strictEqual(nor(unit('dm'), unit('m')), true) + assert.strictEqual(nor(unit('-100cm'), unit('-10inch')), false) + assert.strictEqual(nor(unit(5, 'km'), unit(100, 'gram')), false) + assert.strictEqual(nor(unit(5, 'km'), unit(0, 'gram')), false) + assert.strictEqual(nor(unit(0, 'km'), unit(100, 'gram')), false) + assert.strictEqual(nor(unit(0, 'km'), unit(0, 'gram')), true) + + assert.strictEqual(nor(unit(bignumber(0), 'm'), unit(bignumber(0), 'm')), true) + assert.strictEqual(nor(unit(bignumber(1), 'm'), unit(bignumber(0), 'm')), false) + assert.strictEqual(nor(unit(bignumber(0), 'm'), unit(bignumber(1), 'm')), false) + assert.strictEqual(nor(unit(bignumber(1), 'm'), unit(bignumber(1), 'm')), false) + }) + + it('should nor two arrays', function () { + assert.deepStrictEqual(nor([0, 1, 0, 12], [0, 0, 1, 22]), [true, false, false, false]) + assert.deepStrictEqual(nor([], []), []) + }) + + it('should nor mixed numbers and arrays', function () { + assert.deepStrictEqual(nor(10, [0, 2]), [false, false]) + assert.deepStrictEqual(nor([0, 2], 10), [false, false]) + assert.deepStrictEqual(nor(0, [0, 2]), [true, false]) + assert.deepStrictEqual(nor([0, 2], 0), [true, false]) + }) + + describe('Array', function () { + it('should nor array - scalar', function () { + assert.deepStrictEqual(nor(10, [0, 2]), [false, false]) + assert.deepStrictEqual(nor([0, 2], 10), [false, false]) + }) + + it('should nor array - array', function () { + assert.deepStrictEqual(nor([0, 1, 0, 12], [0, 0, 1, 22]), [true, false, false, false]) + assert.deepStrictEqual(nor([], []), []) + }) + + it('should nor broadcastable arrays', function () { + assert.deepStrictEqual(nor([[0, 1, 0, 12]], [[0], [0], [1], [22]]), [[true, false, true, false], [true, false, true, false], [false, false, false, false], [false, false, false, false]]) + }) + + it('should nor array - dense matrix', function () { + assert.deepStrictEqual(nor([0, 1, 0, 12], matrix([0, 0, 1, 22])), matrix([true, false, false, false])) + assert.deepStrictEqual(nor([], matrix([])), matrix([])) + }) + + it('should nor array - sparse matrix', function () { + assert.deepStrictEqual(nor([[0, 1], [0, 12]], sparse([[0, 0], [1, 22]])), matrix([[true, false], [false, false]])) + }) + }) + + describe('DenseMatrix', function () { + it('should nor dense matrix - scalar', function () { + assert.deepStrictEqual(nor(10, matrix([0, 2])), matrix([false, false])) + assert.deepStrictEqual(nor(matrix([0, 2]), 10), matrix([false, false])) + }) + + it('should nor dense matrix - array', function () { + assert.deepStrictEqual(nor(matrix([0, 1, 0, 12]), [0, 0, 1, 22]), matrix([true, false, false, false])) + assert.deepStrictEqual(nor(matrix([]), []), matrix([])) + }) + + it('should nor dense matrix - dense matrix', function () { + assert.deepStrictEqual(nor(matrix([0, 1, 0, 12]), matrix([0, 0, 1, 22])), matrix([true, false, false, false])) + assert.deepStrictEqual(nor(matrix([]), matrix([])), matrix([])) + }) + + it('should nor dense matrix - sparse matrix', function () { + assert.deepStrictEqual(nor(matrix([[0, 1], [0, 12]]), sparse([[0, 0], [1, 22]])), matrix([[true, false], [false, false]])) + }) + }) + + describe('SparseMatrix', function () { + it('should nor sparse matrix - scalar', function () { + assert.deepStrictEqual(nor(10, sparse([[0], [2]])), matrix([[false], [false]])) + assert.deepStrictEqual(nor(sparse([[0], [2]]), 10), matrix([[false], [false]])) + }) + + it('should nor sparse matrix - array', function () { + assert.deepStrictEqual(nor(sparse([[0, 1], [0, 12]]), [[0, 0], [1, 22]]), matrix([[true, false], [false, false]])) + }) + + it('should nor sparse matrix - dense matrix', function () { + assert.deepStrictEqual(nor(sparse([[0, 1], [0, 12]]), matrix([[0, 0], [1, 22]])), matrix([[true, false], [false, false]])) + }) + + it('should nor sparse matrix - sparse matrix', function () { + assert.deepStrictEqual(nor(sparse([[0, 1], [0, 12]]), sparse([[0, 0], [1, 22]])), sparse([[true, false], [false, false]])) + }) + }) + + it('should throw an error in case of invalid number of arguments', function () { + assert.throws(function () { nor(1) }, /TypeError: Too few arguments/) + assert.throws(function () { nor(1, 2, 3) }, /TypeError: Too many arguments/) + }) + + it('should throw an error in case of invalid type of arguments', function () { + assert.throws(function () { nor(2, null) }, /TypeError: Unexpected type of argument/) + assert.throws(function () { nor(new Date(), false) }, /TypeError: Unexpected type of argument/) + assert.throws(function () { nor(false, new Date()) }, /TypeError: Unexpected type of argument/) + assert.throws(function () { nor(false, undefined) }, /TypeError: Unexpected type of argument/) + assert.throws(function () { nor(undefined, false) }, /TypeError: Unexpected type of argument/) + }) + + it('should LaTeX nor', function () { + const expression = math.parse('nor(1,2)') + assert.strictEqual(expression.toTex(), '\\left(1\\downarrow2\\right)') + }) +}) diff --git a/test/unit-tests/plain/number/logical.test.js b/test/unit-tests/plain/number/logical.test.js new file mode 100644 index 0000000000..ad42b7072d --- /dev/null +++ b/test/unit-tests/plain/number/logical.test.js @@ -0,0 +1,30 @@ +import assert from 'assert' +import { nandNumber, norNumber } from '../../../../src/plain/number/logical.js' + +describe('nor/nand', function () { + it('nor should return true when both are 0', function () { + assert.strictEqual(norNumber(0, 0), true) + }) + + it('nor should return false when one is 0 and the other is 1', function () { + assert.strictEqual(norNumber(1, 0), false) + assert.strictEqual(norNumber(0, 1), false) + }) + + it('nor should return false when both are 1', function () { + assert.strictEqual(norNumber(1, 1), false) + }) + + it('nand should return true when both are 0', function () { + assert.strictEqual(nandNumber(0, 0), true) + }) + + it('nand should return true when one is 0 and the other is 1', function () { + assert.strictEqual(nandNumber(1, 0), true) + assert.strictEqual(nandNumber(0, 1), true) + }) + + it('nand should return false when both are 1', function () { + assert.strictEqual(nandNumber(1, 1), false) + }) +}) diff --git a/types/index.d.ts b/types/index.d.ts index 05b2711423..b9beff7cb0 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -360,7 +360,9 @@ export interface ObjectNodeCtor { export type OperatorNodeMap = { xor: 'xor' and: 'and' + nand: 'nand' or: 'or' + nor: 'nor' bitOr: '|' bitXor: '^|' bitAnd: '&' @@ -1879,6 +1881,18 @@ export interface MathJsInstance extends MathJsFactory { y: number | BigNumber | bigint | Complex | Unit | MathCollection ): boolean | MathCollection + /** + * Logical nand. Test whether at least one of values is zero. + * For matrices, the function is evaluated element wise. + * @param x First value to nand + * @param y Second value to nand + * @returns Returns true when at least of values is zero or empty balue. + */ + nand( + x: number | BigNumber | bigint | Complex | Unit | MathCollection, + y: number | BigNumber | bigint | Complex | Unit | MathCollection + ): boolean | MathCollection + /** * Logical not. Flips boolean value of a given parameter. For matrices, * the function is evaluated element wise. @@ -1915,6 +1929,18 @@ export interface MathJsInstance extends MathJsFactory { y: number | BigNumber | bigint | Complex | Unit | MathCollection ): boolean | MathCollection + /** + * Logical nor. Test if both of values are zero + * For matrices, the function is evaluated element wise. + * @param x First value to nor + * @param y Second value to nor + * @returns Returns true when both of the inputs are defined with zero. + */ + nor( + x: number | BigNumber | bigint | Complex | Unit | MathCollection, + y: number | BigNumber | bigint | Complex | Unit | MathCollection + ): boolean | MathCollection + /** * Logical xor. Test whether one and only one value is defined with a * nonzero/nonempty value. For matrices, the function is evaluated @@ -4092,9 +4118,11 @@ export const { // logical dependencies andDependencies, + nandDependencies, notDependencies, nullishDependencies, orDependencies, + norDependencies, xorDependencies, // matrix function dependencies @@ -5978,6 +6006,18 @@ export interface MathJsChain { * Logical functions ************************************************************************/ + /** + * Logical nand. Test whether at least one of values is zero. + * For matrices, the function is evaluated element wise. + * @param y Second value to nand + */ + nand( + this: MathJsChain< + number | BigNumber | bigint | Complex | Unit | MathCollection + >, + y: number | BigNumber | bigint | Complex | Unit | MathCollection + ): MathJsChain + /** * Logical and. Test whether two values are both defined with a * nonzero/nonempty value. For matrices, the function is evaluated @@ -6024,6 +6064,18 @@ export interface MathJsChain { y: number | BigNumber | bigint | Complex | Unit | MathCollection ): MathJsChain + /** + * Logical nor. Test if both of value are defined with zero. + * For matrices, the function is evaluated element wise. + * @param y Second value to nor + */ + nor( + this: MathJsChain< + number | BigNumber | bigint | Complex | Unit | MathCollection + >, + y: number | BigNumber | bigint | Complex | Unit | MathCollection + ): MathJsChain + /** * Logical xor. Test whether one and only one value is defined with a * nonzero/nonempty value. For matrices, the function is evaluated @@ -7632,9 +7684,11 @@ export const { // logical and, + nand, not, nullish, or, + nor, xor, // matrix functions