Skip to content

Instantly share code, notes, and snippets.

@petejkim
Last active August 26, 2020 01:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save petejkim/05234d36a989ae4665132e8b4404de5b to your computer and use it in GitHub Desktop.
Save petejkim/05234d36a989ae4665132e8b4404de5b to your computer and use it in GitHub Desktop.
BN <-> Decimal String
test("decimalStringFromBN", () => {
expect(types.decimalStringFromBN(new BN(0))).toEqual("0");
expect(types.decimalStringFromBN(new BN(0), 1)).toEqual("0");
expect(types.decimalStringFromBN(new BN(1000000))).toEqual("1000000");
expect(types.decimalStringFromBN(new BN(1000000), 1)).toEqual("100000");
expect(types.decimalStringFromBN(new BN(1000001), 1)).toEqual("100000.1");
expect(types.decimalStringFromBN(new BN(1000100), 1)).toEqual("100010");
expect(types.decimalStringFromBN(new BN(1000000), 2)).toEqual("10000");
expect(types.decimalStringFromBN(new BN(1000001), 2)).toEqual("10000.01");
expect(types.decimalStringFromBN(new BN(1000100), 2)).toEqual("10001");
expect(types.decimalStringFromBN(new BN(1000000), 5)).toEqual("10");
expect(types.decimalStringFromBN(new BN(1000001), 5)).toEqual("10.00001");
expect(types.decimalStringFromBN(new BN(1000100), 5)).toEqual("10.001");
expect(types.decimalStringFromBN(new BN(1000000), 6)).toEqual("1");
expect(types.decimalStringFromBN(new BN(1000001), 6)).toEqual("1.000001");
expect(types.decimalStringFromBN(new BN(1000100), 6)).toEqual("1.0001");
expect(types.decimalStringFromBN(new BN(1000000), 7)).toEqual("0.1");
expect(types.decimalStringFromBN(new BN(1000001), 7)).toEqual("0.1000001");
expect(types.decimalStringFromBN(new BN(1000100), 7)).toEqual("0.10001");
expect(types.decimalStringFromBN(new BN(1000000), 8)).toEqual("0.01");
expect(types.decimalStringFromBN(new BN(1000001), 8)).toEqual("0.01000001");
expect(types.decimalStringFromBN(new BN(1000100), 8)).toEqual("0.010001");
expect(types.decimalStringFromBN(new BN(1000000), 10)).toEqual("0.0001");
expect(types.decimalStringFromBN(new BN(1000001), 10)).toEqual(
"0.0001000001"
);
expect(types.decimalStringFromBN(new BN(1000100), 10)).toEqual("0.00010001");
expect(types.decimalStringFromBN(new BN("3141592653589793238"), 18)).toEqual(
"3.141592653589793238"
);
expect(() => types.decimalStringFromBN(new BN(-1))).toThrow();
});
test("bnFromDecimalString", () => {
expect(types.bnFromDecimalString("0")).toEqual(new BN(0));
expect(types.bnFromDecimalString("0", 1)).toEqual(new BN(0));
expect(types.bnFromDecimalString("1000000")).toEqual(new BN(1000000));
expect(types.bnFromDecimalString("100000", 1)).toEqual(new BN(1000000));
expect(types.bnFromDecimalString("100000.1", 1)).toEqual(new BN(1000001));
expect(types.bnFromDecimalString("100010", 1)).toEqual(new BN(1000100));
expect(types.bnFromDecimalString("10000", 2)).toEqual(new BN(1000000));
expect(types.bnFromDecimalString("10000.01", 2)).toEqual(new BN(1000001));
expect(types.bnFromDecimalString("10001", 2)).toEqual(new BN(1000100));
expect(types.bnFromDecimalString("10", 5)).toEqual(new BN(1000000));
expect(types.bnFromDecimalString("10.00001", 5)).toEqual(new BN(1000001));
expect(types.bnFromDecimalString("10.001", 5)).toEqual(new BN(1000100));
expect(types.bnFromDecimalString("1", 6)).toEqual(new BN(1000000));
expect(types.bnFromDecimalString("1.000001", 6)).toEqual(new BN(1000001));
expect(types.bnFromDecimalString("1.0001", 6)).toEqual(new BN(1000100));
expect(types.bnFromDecimalString("0.1", 7)).toEqual(new BN(1000000));
expect(types.bnFromDecimalString("0.1000001", 7)).toEqual(new BN(1000001));
expect(types.bnFromDecimalString("0.10001", 7)).toEqual(new BN(1000100));
expect(types.bnFromDecimalString("0.01", 8)).toEqual(new BN(1000000));
expect(types.bnFromDecimalString("0.01000001", 8)).toEqual(new BN(1000001));
expect(types.bnFromDecimalString("0.010001", 8)).toEqual(new BN(1000100));
expect(types.bnFromDecimalString("0.0001", 10)).toEqual(new BN(1000000));
expect(types.bnFromDecimalString("0.0001000001", 10)).toEqual(
new BN(1000001)
);
expect(types.bnFromDecimalString("0.00010001", 10)).toEqual(new BN(1000100));
expect(types.bnFromDecimalString("3.141592653589793238", 18)).toEqual(
new BN("3141592653589793238")
);
expect(types.bnFromDecimalString(".", 1)).toEqual(new BN(0));
expect(types.bnFromDecimalString("1.", 1)).toEqual(new BN(10));
expect(types.bnFromDecimalString(".1", 1)).toEqual(new BN(1));
expect(types.bnFromDecimalString(".1", 2)).toEqual(new BN(10));
expect(types.bnFromDecimalString(".10", 2)).toEqual(new BN(10));
expect(types.bnFromDecimalString("1.", 2)).toEqual(new BN(100));
expect(types.bnFromDecimalString("3.14159265", 2)).toEqual(new BN(314));
expect(() => types.bnFromDecimalString("-1")).toThrow();
});
/**
* @license
* Copyright (c) 2020 petejkim
* SPDX-License-Identifier: MIT
*/
/**
* Convert a BN object to a string representation of a positive decimal number
* @param bn BN object
* @param decimalPlaces Number of decimal places
* @returns String representation of a positive decimal number
*/
export function decimalStringFromBN(bn: BN, decimalPlaces = 0): string {
if (bn.isNeg()) {
throw new Error("Number must be positive");
}
if (bn.isZero()) {
return "0";
}
let str = bn.toString(10).padStart(decimalPlaces + 1, "0");
if (decimalPlaces === 0) {
return str;
}
str = str.slice(0, -decimalPlaces) + "." + str.slice(-decimalPlaces);
str = str.replace(/\.0+$/, "");
if (str.includes(".")) {
str = str.replace(/0+$/, "");
}
return str;
}
/**
* Convert a string representation of a positive decimal number to BN object
* @param decimalNumber String representation of a positive decimal number
* @param decimalPlaces Number of decimal places
* @returns BN object
* @throws Error
*/
export function bnFromDecimalString(
decimalNumber: string,
decimalPlaces = 0
): BN {
if (decimalNumber.startsWith("-")) {
throw new Error("Number must be positive");
}
if (!decimalNumber || !/^\d*(\.\d*)?$/.test(decimalNumber)) {
throw new Error("Invalid string representation of a decimal number");
}
let [whole, fractional] = decimalNumber.split(".");
whole = whole || "0";
fractional = (fractional || "0")
.slice(0, decimalPlaces)
.padEnd(decimalPlaces, "0");
return new BN(whole + fractional, 10);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment