diff --git a/CHANGELOG.md b/CHANGELOG.md index aa2e526282..fec556a339 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ and this project adheres to ## [Unreleased] +### Added + +- @cosmjs/math: Add `Decimal.zero` and `Decimal.one` ([#1110]). + +[#1110]: https://github.com/cosmos/cosmjs/issues/1110 + ## [0.28.3] - 2022-04-11 ### Added diff --git a/packages/math/src/decimal.spec.ts b/packages/math/src/decimal.spec.ts index e12d1f96db..1526c9260e 100644 --- a/packages/math/src/decimal.spec.ts +++ b/packages/math/src/decimal.spec.ts @@ -133,6 +133,50 @@ describe("Decimal", () => { }); }); + describe("zero", () => { + it("works", () => { + expect(Decimal.zero(0).toString()).toEqual("0"); + expect(Decimal.zero(1).toString()).toEqual("0"); + expect(Decimal.zero(2).toString()).toEqual("0"); + expect(Decimal.zero(30).toString()).toEqual("0"); + + expect(Decimal.zero(0).fractionalDigits).toEqual(0); + expect(Decimal.zero(1).fractionalDigits).toEqual(1); + expect(Decimal.zero(2).fractionalDigits).toEqual(2); + expect(Decimal.zero(30).fractionalDigits).toEqual(30); + + expect(Decimal.zero(0).atomics).toEqual("0"); + expect(Decimal.zero(1).atomics).toEqual("0"); + expect(Decimal.zero(2).atomics).toEqual("0"); + expect(Decimal.zero(30).atomics).toEqual("0"); + + expect(() => Decimal.zero(NaN)).toThrowError(/Fractional digits is not an integer/i); + expect(() => Decimal.zero(1.2)).toThrowError(/Fractional digits is not an integer/i); + }); + }); + + describe("one", () => { + it("works", () => { + expect(Decimal.one(0).toString()).toEqual("1"); + expect(Decimal.one(1).toString()).toEqual("1"); + expect(Decimal.one(2).toString()).toEqual("1"); + expect(Decimal.one(30).toString()).toEqual("1"); + + expect(Decimal.one(0).fractionalDigits).toEqual(0); + expect(Decimal.one(1).fractionalDigits).toEqual(1); + expect(Decimal.one(2).fractionalDigits).toEqual(2); + expect(Decimal.one(30).fractionalDigits).toEqual(30); + + expect(Decimal.one(0).atomics).toEqual("1"); + expect(Decimal.one(1).atomics).toEqual("10"); + expect(Decimal.one(2).atomics).toEqual("100"); + expect(Decimal.one(30).atomics).toEqual("1000000000000000000000000000000"); + + expect(() => Decimal.one(NaN)).toThrowError(/Fractional digits is not an integer/i); + expect(() => Decimal.one(1.2)).toThrowError(/Fractional digits is not an integer/i); + }); + }); + describe("toString", () => { it("displays no decimal point for full numbers", () => { expect(Decimal.fromUserInput("44", 0).toString()).toEqual("44"); diff --git a/packages/math/src/decimal.ts b/packages/math/src/decimal.ts index 3f548e5b8d..6bb8a1f69a 100644 --- a/packages/math/src/decimal.ts +++ b/packages/math/src/decimal.ts @@ -58,6 +58,28 @@ export class Decimal { return new Decimal(atomics, fractionalDigits); } + /** + * Creates a Decimal with value 0.0 and the given number of fractial digits. + * + * Fractional digits are not relevant for the value but needed to be able + * to perform arithmetic operations with other decimals. + */ + public static zero(fractionalDigits: number): Decimal { + Decimal.verifyFractionalDigits(fractionalDigits); + return new Decimal("0", fractionalDigits); + } + + /** + * Creates a Decimal with value 1.0 and the given number of fractial digits. + * + * Fractional digits are not relevant for the value but needed to be able + * to perform arithmetic operations with other decimals. + */ + public static one(fractionalDigits: number): Decimal { + Decimal.verifyFractionalDigits(fractionalDigits); + return new Decimal("1" + "0".repeat(fractionalDigits), fractionalDigits); + } + private static verifyFractionalDigits(fractionalDigits: number): void { if (!Number.isInteger(fractionalDigits)) throw new Error("Fractional digits is not an integer"); if (fractionalDigits < 0) throw new Error("Fractional digits must not be negative");