( item: Expression, mode: 'Min' | 'Max' | 'Supremum' | 'Infimum' )
| 2693 | if (x.isNonNegative === true) return 'non-negative'; |
| 2694 | if (n.isOdd === true || (n.numerator.isOdd && n.denominator.isOdd)) { |
| 2695 | return x.sgn; |
| 2696 | } |
| 2697 | if (x.isNegative && n.isOdd === false) return 'unsigned'; |
| 2698 | return undefined; |
| 2699 | }, |
| 2700 | canonical: (args, { engine }) => { |
| 2701 | args = checkNumericArgs(engine, args, 2); |
| 2702 | const [base, exp] = args; |
| 2703 | //note: args. are canonicalized prior. |
| 2704 | return canonicalRoot(base, exp); |
| 2705 | }, |
| 2706 | evaluate: ([x, n], { numericApproximation, engine }) => { |
| 2707 | // Non-lazy: operands are already evaluated by the driver. |
| 2708 | const nonNumeric = nonNumericOperandError(engine, [x, n]); |
| 2709 | if (nonNumeric !== undefined) return nonNumeric; |
| 2710 | const evalX = x; |
| 2711 | if (evalX.operator === 'Quantity') { |
| 2712 | const nVal = n.re; |
| 2713 | if (nVal !== undefined && nVal !== 0) { |
| 2714 | const r = quantityPower(engine, evalX, engine.number(1 / nVal)); |
| 2715 | if ( |
| 2716 | numericApproximation && |
| 2717 | r && |
| 2718 | isQuantity(r) && |
| 2719 | isMeasurement(r.op1) |
| 2720 | ) |
| 2721 | return r.N(); |
| 2722 | return r; |
| 2723 | } |
| 2724 | } |
| 2725 | if (isMeasurement(evalX)) { |
| 2726 | const r = measurementRoot(engine, evalX, n); |
| 2727 | return numericApproximation ? r?.N() : r; |
| 2728 | } |
| 2729 | // D2: an inexact (float) radicand or index numericizes even under |
| 2730 | // plain evaluate() — `Root(5.1, 3)` → 1.721…; `isExactNumber` |
| 2731 | // protects an exact Gaussian-integer radicand (see `Power`). |
| 2732 | return root(x, n, { |
| 2733 | numericApproximation: shouldNumericize(numericApproximation, x, n), |
| 2734 | }); |
| 2735 | }, |
| 2736 | }, |
| 2737 | |
| 2738 | Remainder: { |
| 2739 | description: |
| 2740 | 'IEEE remainder: the signed remainder after dividing x by y, with the quotient rounded to the nearest integer (ties round toward +Infinity, matching JavaScript `Math.round`)', |
| 2741 | complexity: 2500, |
| 2742 | broadcastable: true, |
| 2743 | signature: '(T, T) -> T where T: number', |
| 2744 | evaluate: ([a, b]) => |
| 2745 | apply2( |
| 2746 | a, |
| 2747 | b, |
| 2748 | (a, b) => a - b * Math.round(a / b), |
| 2749 | // `BigDecimal.round()` rounds ties away from zero, which disagrees |
| 2750 | // with `Math.round`'s ties-toward-+Infinity at half-integer |
| 2751 | // quotients (e.g. Remainder(-5, 2): machine lane rounds -2.5 to |
| 2752 | // -2, bignum `.round()` would round it to -3, flipping the result |
no test coverage detected