Skip to content
This repository has been archived by the owner on Jan 15, 2025. It is now read-only.

Remove inofficial rounding modes #107

Merged
merged 2 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [14.0.0] - 2024-04-30

### Removed

- Unsupported/inofficial rounding modes. We support the official IEEE Decimal128 ones: trunc, ceil, floor, halfEven, halfUp.

## [13.0.0] - 2024-04-24

### Removed
Expand Down
195 changes: 1 addition & 194 deletions src/decimal128.mts
Original file line number Diff line number Diff line change
Expand Up @@ -393,41 +393,6 @@ function roundFloor(x: SignedSignificandExponent): SignedSignificandExponent {
};
}

function roundExpand(x: SignedSignificandExponent): SignedSignificandExponent {
let sig = x.significand.toString();
let lastDigit = parseInt(sig.charAt(MAX_SIGNIFICANT_DIGITS)) as Digit;
let cutoff = cutoffAfterSignificantDigits(sig, MAX_SIGNIFICANT_DIGITS - 1);
let penultimateDigit = parseInt(
sig.charAt(MAX_SIGNIFICANT_DIGITS - 1)
) as Digit;
let excessDigits = sig.substring(MAX_SIGNIFICANT_DIGITS);
let numExcessDigits = excessDigits.length;
let exp = x.exponent + numExcessDigits; // we will chop off the excess digits

let finalDigit = roundIt(
x.isNegative,
penultimateDigit,
lastDigit,
ROUNDING_MODE_EXPAND
);

if (finalDigit < 10) {
return {
isNegative: x.isNegative,
significand: BigInt(`${cutoff}${finalDigit}`),
exponent: exp,
};
}

let rounded = propagateCarryFromRight(cutoff);

return {
isNegative: x.isNegative,
significand: BigInt(`${rounded}0`),
exponent: exp,
};
}

function roundTrunc(x: SignedSignificandExponent): SignedSignificandExponent {
let sig = x.significand.toString();
let lastDigit = parseInt(sig.charAt(MAX_SIGNIFICANT_DIGITS)) as Digit;
Expand All @@ -453,43 +418,6 @@ function roundTrunc(x: SignedSignificandExponent): SignedSignificandExponent {
};
}

function roundHalfExpand(
x: SignedSignificandExponent
): SignedSignificandExponent {
let sig = x.significand.toString();
let lastDigit = parseInt(sig.charAt(MAX_SIGNIFICANT_DIGITS)) as Digit;
let cutoff = cutoffAfterSignificantDigits(sig, MAX_SIGNIFICANT_DIGITS - 1);
let penultimateDigit = parseInt(
sig.charAt(MAX_SIGNIFICANT_DIGITS - 1)
) as Digit;
let excessDigits = sig.substring(MAX_SIGNIFICANT_DIGITS);
let numExcessDigits = excessDigits.length;
let exp = x.exponent + numExcessDigits; // we will chop off the excess digits

let finalDigit = roundIt(
x.isNegative,
penultimateDigit,
lastDigit,
ROUNDING_MODE_HALF_EXPAND
);

if (finalDigit < 10) {
return {
isNegative: x.isNegative,
significand: BigInt(`${cutoff}${finalDigit}`),
exponent: exp,
};
}

let rounded = propagateCarryFromRight(cutoff);

return {
isNegative: x.isNegative,
significand: BigInt(`${rounded}0`),
exponent: exp,
};
}

function roundHalfCeil(
x: SignedSignificandExponent
): SignedSignificandExponent {
Expand Down Expand Up @@ -517,70 +445,6 @@ function roundHalfCeil(
};
}

function roundHalfFloor(
x: SignedSignificandExponent
): SignedSignificandExponent {
let sig = x.significand.toString();
let lastDigit = parseInt(sig.charAt(MAX_SIGNIFICANT_DIGITS)) as Digit;
let cutoff = cutoffAfterSignificantDigits(sig, MAX_SIGNIFICANT_DIGITS - 1);
let penultimateDigit = parseInt(
sig.charAt(MAX_SIGNIFICANT_DIGITS - 1)
) as Digit;
let excessDigits = sig.substring(MAX_SIGNIFICANT_DIGITS);
let numExcessDigits = excessDigits.length;
let exp = x.exponent + numExcessDigits; // we will chop off the excess digits

let finalDigit = roundIt(
x.isNegative,
penultimateDigit,
lastDigit,
ROUNDING_MODE_HALF_FLOOR
);

if (finalDigit < 10) {
return {
isNegative: x.isNegative,
significand: BigInt(`${cutoff}${finalDigit}`),
exponent: exp,
};
}

let rounded = propagateCarryFromRight(cutoff);

return {
isNegative: x.isNegative,
significand: BigInt(`${rounded}0`),
exponent: exp,
};
}

function roundHalfTrunc(
x: SignedSignificandExponent
): SignedSignificandExponent {
let sig = x.significand.toString();
let lastDigit = parseInt(sig.charAt(MAX_SIGNIFICANT_DIGITS)) as Digit;
let cutoff = cutoffAfterSignificantDigits(sig, MAX_SIGNIFICANT_DIGITS - 1);
let penultimateDigit = parseInt(
sig.charAt(MAX_SIGNIFICANT_DIGITS - 1)
) as Digit;
let excessDigits = sig.substring(MAX_SIGNIFICANT_DIGITS);
let numExcessDigits = excessDigits.length;
let exp = x.exponent + numExcessDigits; // we will chop off the excess digits

let finalDigit = roundIt(
x.isNegative,
penultimateDigit,
lastDigit,
ROUNDING_MODE_HALF_TRUNCATE
);

return {
isNegative: x.isNegative,
significand: BigInt(`${cutoff}${finalDigit}`),
exponent: exp,
};
}

function adjustNonInteger(
x: SignedSignificandExponent,
options: FullySpecifiedConstructorOptions
Expand All @@ -592,18 +456,10 @@ function adjustNonInteger(
return roundCeiling(x);
case ROUNDING_MODE_FLOOR:
return roundFloor(x);
case ROUNDING_MODE_EXPAND:
return roundExpand(x);
case ROUNDING_MODE_TRUNCATE:
return roundTrunc(x);
case ROUNDING_MODE_HALF_EXPAND:
return roundHalfExpand(x);
case ROUNDING_MODE_HALF_CEILING:
return roundHalfCeil(x);
case ROUNDING_MODE_HALF_FLOOR:
return roundHalfFloor(x);
case ROUNDING_MODE_HALF_TRUNCATE:
return roundHalfTrunc(x);
default:
return roundHalfEven(x);
}
Expand Down Expand Up @@ -718,13 +574,9 @@ function handleInfinity(s: string): Decimal128Constructor {

export const ROUNDING_MODE_CEILING: RoundingMode = "ceil";
export const ROUNDING_MODE_FLOOR: RoundingMode = "floor";
export const ROUNDING_MODE_EXPAND: RoundingMode = "expand";
export const ROUNDING_MODE_TRUNCATE: RoundingMode = "trunc";
export const ROUNDING_MODE_HALF_EVEN: RoundingMode = "halfEven";
export const ROUNDING_MODE_HALF_EXPAND: RoundingMode = "halfExpand";
export const ROUNDING_MODE_HALF_CEILING: RoundingMode = "halfCeil";
export const ROUNDING_MODE_HALF_FLOOR: RoundingMode = "halfFloor";
export const ROUNDING_MODE_HALF_TRUNCATE: RoundingMode = "halfTrunc";

const ROUNDING_MODE_DEFAULT = ROUNDING_MODE_HALF_EVEN;
const CONSTRUCTOR_SHOULD_NORMALIZE = false;
Expand Down Expand Up @@ -756,8 +608,6 @@ function roundIt(
}

return digitToRound;
case ROUNDING_MODE_EXPAND:
return (digitToRound + 1) as DigitOrTen;
case ROUNDING_MODE_TRUNCATE:
return digitToRound;
case ROUNDING_MODE_HALF_CEILING:
Expand All @@ -769,36 +619,6 @@ function roundIt(
return (digitToRound + 1) as DigitOrTen;
}

return digitToRound;
case ROUNDING_MODE_HALF_FLOOR:
if (decidingDigit === 5) {
if (isNegative) {
return (digitToRound + 1) as DigitOrTen;
}

return digitToRound;
}

if (decidingDigit > 5) {
return (digitToRound + 1) as DigitOrTen;
}

return digitToRound;
case ROUNDING_MODE_HALF_TRUNCATE:
if (decidingDigit === 5) {
return digitToRound;
}

if (decidingDigit > 5) {
return (digitToRound + 1) as DigitOrTen;
}

return digitToRound;
case ROUNDING_MODE_HALF_EXPAND:
if (decidingDigit >= 5) {
return (digitToRound + 1) as DigitOrTen;
}

return digitToRound;
default: // ROUNDING_MODE_HALF_EVEN:
if (decidingDigit === 5) {
Expand All @@ -817,27 +637,14 @@ function roundIt(
}
}

type RoundingMode =
| "ceil"
| "floor"
| "expand"
| "trunc"
| "halfEven"
| "halfExpand"
| "halfCeil"
| "halfFloor"
| "halfTrunc";
type RoundingMode = "ceil" | "floor" | "trunc" | "halfEven" | "halfCeil";

const ROUNDING_MODES: RoundingMode[] = [
"ceil",
"floor",
"expand",
"trunc",
"halfEven",
"halfExpand",
"halfCeil",
"halfFloor",
"halfTrunc",
];

const digitStrRegExp =
Expand Down
8 changes: 0 additions & 8 deletions tests/constructor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -464,13 +464,9 @@ describe("rounding options", () => {
let answers = {
ceil: "-1234567890123456789012345678901234",
floor: "-1234567890123456789012345678901235",
expand: "-1234567890123456789012345678901235",
trunc: "-1234567890123456789012345678901234",
halfEven: "-1234567890123456789012345678901234",
halfExpand: "-1234567890123456789012345678901235",
halfCeil: "-1234567890123456789012345678901234",
halfFloor: "-1234567890123456789012345678901235",
halfTrunc: "-1234567890123456789012345678901234",
};
for (const [mode, expected] of Object.entries(answers)) {
test(`constructor with rounding mode "${mode}"`, () => {
Expand All @@ -485,13 +481,9 @@ describe("rounding options", () => {
let roundUpAnswers = {
ceil: "-1234567890123456789012345678901239",
floor: "-1234567890123456789012345678901240",
expand: "-1234567890123456789012345678901240",
trunc: "-1234567890123456789012345678901239",
halfEven: "-1234567890123456789012345678901240",
halfExpand: "-1234567890123456789012345678901240",
halfCeil: "-1234567890123456789012345678901239",
halfFloor: "-1234567890123456789012345678901240",
halfTrunc: "-1234567890123456789012345678901239",
};
for (const [mode, expected] of Object.entries(roundUpAnswers)) {
test(`constructor with rounding mode "${mode}"`, () => {
Expand Down
Loading