Next.js website for Rocky Mountain Vending company featuring: - Product catalog with Stripe integration - Service areas and parts pages - Admin dashboard with Clerk authentication - SEO optimized pages with JSON-LD structured data Co-authored-by: Cursor <cursoragent@cursor.com>
148 lines
5.3 KiB
Text
148 lines
5.3 KiB
Text
import Decimal from 'decimal.js';
|
|
import { ZERO } from '../constants';
|
|
import { invariant, repeat } from '../utils';
|
|
import { ApplyUnsignedRoundingMode } from './ApplyUnsignedRoundingMode';
|
|
//IMPL: Helper function to find n1, e1, and r1
|
|
function findN1E1R1(x, p) {
|
|
var maxN1 = Decimal.pow(10, p);
|
|
var minN1 = Decimal.pow(10, p - 1);
|
|
var maxE1 = x.div(minN1).log(10).plus(p).minus(1).ceil();
|
|
var currentE1 = maxE1;
|
|
while (true) {
|
|
var currentN1 = x.div(Decimal.pow(10, currentE1.minus(p).plus(1))).floor();
|
|
if (currentN1.lessThan(maxN1) && currentN1.greaterThanOrEqualTo(minN1)) {
|
|
var currentR1 = currentN1.times(Decimal.pow(10, currentE1.minus(p).plus(1)));
|
|
if (currentR1.lessThanOrEqualTo(x)) {
|
|
return {
|
|
n1: currentN1,
|
|
e1: currentE1,
|
|
r1: currentR1,
|
|
};
|
|
}
|
|
}
|
|
currentE1 = currentE1.minus(1);
|
|
}
|
|
}
|
|
//IMPL: Helper function to find n2, e2, and r2
|
|
function findN2E2R2(x, p) {
|
|
var maxN2 = Decimal.pow(10, p);
|
|
var minN2 = Decimal.pow(10, p - 1);
|
|
var minE2 = x.div(maxN2).log(10).plus(p).minus(1).floor();
|
|
var currentE2 = minE2;
|
|
while (true) {
|
|
var currentN2 = x.div(Decimal.pow(10, currentE2.minus(p).plus(1))).ceil();
|
|
if (currentN2.lessThan(maxN2) && currentN2.greaterThanOrEqualTo(minN2)) {
|
|
var currentR2 = currentN2.times(Decimal.pow(10, currentE2.minus(p).plus(1)));
|
|
if (currentR2.greaterThanOrEqualTo(x)) {
|
|
return {
|
|
n2: currentN2,
|
|
e2: currentE2,
|
|
r2: currentR2,
|
|
};
|
|
}
|
|
}
|
|
currentE2 = currentE2.plus(1);
|
|
}
|
|
}
|
|
/**
|
|
* https://tc39.es/ecma402/#sec-torawprecision
|
|
* @param x a finite non-negative Number or BigInt
|
|
* @param minPrecision an integer between 1 and 21
|
|
* @param maxPrecision an integer between 1 and 21
|
|
*/
|
|
export function ToRawPrecision(x, minPrecision, maxPrecision, unsignedRoundingMode) {
|
|
// 1. Let p be maxPrecision.
|
|
var p = maxPrecision;
|
|
var m;
|
|
var e;
|
|
var xFinal;
|
|
// 2. If x = 0, then
|
|
if (x.isZero()) {
|
|
// a. Let m be the String value consisting of p occurrences of the character "0".
|
|
m = repeat('0', p);
|
|
// b. Let e be 0.
|
|
e = 0;
|
|
// c. Let xFinal be 0.
|
|
xFinal = ZERO;
|
|
}
|
|
else {
|
|
// 3. Else,
|
|
// a. Let {n1, e1, r1} be the result of findN1E1R1(x, p).
|
|
var _a = findN1E1R1(x, p), n1 = _a.n1, e1 = _a.e1, r1 = _a.r1;
|
|
// b. Let {n2, e2, r2} be the result of findN2E2R2(x, p).
|
|
var _b = findN2E2R2(x, p), n2 = _b.n2, e2 = _b.e2, r2 = _b.r2;
|
|
// c. Let r be ApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode).
|
|
var r = ApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode);
|
|
var n
|
|
// d. If r = r1, then
|
|
= void 0;
|
|
// d. If r = r1, then
|
|
if (r.eq(r1)) {
|
|
// i. Let n be n1.
|
|
n = n1;
|
|
// ii. Let e be e1.
|
|
e = e1.toNumber();
|
|
// iii. Let xFinal be r1.
|
|
xFinal = r1;
|
|
}
|
|
else {
|
|
// e. Else,
|
|
// i. Let n be n2.
|
|
n = n2;
|
|
// ii. Let e be e2.
|
|
e = e2.toNumber();
|
|
// iii. Let xFinal be r2.
|
|
xFinal = r2;
|
|
}
|
|
// f. Let m be the String representation of n.
|
|
m = n.toString();
|
|
}
|
|
var int;
|
|
// 4. If e ≥ p - 1, then
|
|
if (e >= p - 1) {
|
|
// a. Let m be the string-concatenation of m and p - 1 - e occurrences of the character "0".
|
|
m = m + repeat('0', e - p + 1);
|
|
// b. Let int be e + 1.
|
|
int = e + 1;
|
|
}
|
|
else if (e >= 0) {
|
|
// 5. Else if e ≥ 0, then
|
|
// a. Let m be the string-concatenation of the first e + 1 characters of m, ".", and the remaining p - (e + 1) characters of m.
|
|
m = m.slice(0, e + 1) + '.' + m.slice(m.length - (p - (e + 1)));
|
|
// b. Let int be e + 1.
|
|
int = e + 1;
|
|
}
|
|
else {
|
|
// 6. Else,
|
|
// a. Assert: e < 0.
|
|
invariant(e < 0, 'e should be less than 0');
|
|
// b. Let m be the string-concatenation of "0.", -e - 1 occurrences of the character "0", and m.
|
|
m = '0.' + repeat('0', -e - 1) + m;
|
|
// c. Let int be 1.
|
|
int = 1;
|
|
}
|
|
// 7. If m contains ".", and maxPrecision > minPrecision, then
|
|
if (m.includes('.') && maxPrecision > minPrecision) {
|
|
// a. Let cut be maxPrecision - minPrecision.
|
|
var cut = maxPrecision - minPrecision;
|
|
// b. Repeat, while cut > 0 and the last character of m is "0",
|
|
while (cut > 0 && m[m.length - 1] === '0') {
|
|
// i. Remove the last character from m.
|
|
m = m.slice(0, m.length - 1);
|
|
// ii. Decrease cut by 1.
|
|
cut--;
|
|
}
|
|
// c. If the last character of m is ".", then
|
|
if (m[m.length - 1] === '.') {
|
|
// i. Remove the last character from m.
|
|
m = m.slice(0, m.length - 1);
|
|
}
|
|
}
|
|
// 8. Return the Record { [[FormattedString]]: m, [[RoundedNumber]]: xFinal, [[IntegerDigitsCount]]: int, [[RoundingMagnitude]]: e }.
|
|
return {
|
|
formattedString: m,
|
|
roundedNumber: xFinal,
|
|
integerDigitsCount: int,
|
|
roundingMagnitude: e,
|
|
};
|
|
}
|