Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
37 lines
1.0 KiB
Plaintext
37 lines
1.0 KiB
Plaintext
import "../types/number.js";
|
|
import { invariant } from "../utils.js";
|
|
export function ApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode) {
|
|
// If x equals r1 or if r1 equals r2 (already at rounding boundary), return r1
|
|
if (x.eq(r1) || r1.eq(r2)) return r1;
|
|
// If x equals r2, return r2
|
|
if (x.eq(r2)) return r2;
|
|
invariant(r1.lessThan(x) && x.lessThan(r2), `x should be between r1 and r2 but x=${x}, r1=${r1}, r2=${r2}`);
|
|
if (unsignedRoundingMode === "zero") {
|
|
return r1;
|
|
}
|
|
if (unsignedRoundingMode === "infinity") {
|
|
return r2;
|
|
}
|
|
const d1 = x.minus(r1);
|
|
const d2 = r2.minus(x);
|
|
if (d1.lessThan(d2)) {
|
|
return r1;
|
|
}
|
|
if (d2.lessThan(d1)) {
|
|
return r2;
|
|
}
|
|
invariant(d1.eq(d2), "d1 should be equal to d2");
|
|
if (unsignedRoundingMode === "half-zero") {
|
|
return r1;
|
|
}
|
|
if (unsignedRoundingMode === "half-infinity") {
|
|
return r2;
|
|
}
|
|
invariant(unsignedRoundingMode === "half-even", "unsignedRoundingMode should be half-even");
|
|
const cardinality = r1.div(r2.minus(r1)).mod(2);
|
|
if (cardinality.isZero()) {
|
|
return r1;
|
|
}
|
|
return r2;
|
|
}
|