Created
September 23, 2021 21:52
-
-
Save petejkim/7c43d543916b9bd3cc864b852b01584e to your computer and use it in GitHub Desktop.
decimal string <> BN
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import BN from "bn.js"; | |
import * as types from "./types"; | |
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.", 0)).toEqual(new BN(1)); | |
expect(types.bnFromDecimalString("1.", 1)).toEqual(new BN(10)); | |
expect(types.bnFromDecimalString("1.", 2)).toEqual(new BN(100)); | |
expect(types.bnFromDecimalString(".1", 0)).toEqual(new BN(0)); | |
expect(types.bnFromDecimalString(".1", 1)).toEqual(new BN(1)); | |
expect(types.bnFromDecimalString(".1", 2)).toEqual(new BN(10)); | |
expect(types.bnFromDecimalString(".10", 0)).toEqual(new BN(0)); | |
expect(types.bnFromDecimalString(".10", 1)).toEqual(new BN(1)); | |
expect(types.bnFromDecimalString(".10", 2)).toEqual(new BN(10)); | |
expect(types.bnFromDecimalString("3.14159265", 2)).toEqual(new BN(314)); | |
expect(() => types.bnFromDecimalString("-1")).toThrow(); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import BN from "bn.js"; | |
/** | |
* Convert a BN object to a hexadecimal string | |
* @param bn BN object | |
* @param addPrefix (Default: true) If true, prepends the string with "0x" | |
* @returns Hexadecimal string | |
*/ | |
export function hexStringFromBN(bn: BN, addPrefix = true): string { | |
if (!BN.isBN(bn)) { | |
throw new TypeError("Given value is not a BN object"); | |
} | |
const hex = bn.toString(16); | |
return addPrefix ? "0x" + hex : hex; | |
} | |
/** | |
* 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 | |
* @param varName Variable name to include in the error message | |
* @returns BN object | |
* @throws Error | |
*/ | |
export function bnFromDecimalString( | |
decimalNumber: string, | |
decimalPlaces = 0, | |
varName?: string | |
): BN { | |
ensurePositiveDecimalString(decimalNumber, varName); | |
let [whole, fractional] = decimalNumber.split("."); | |
whole = whole || "0"; | |
fractional = (fractional || "0") | |
.slice(0, decimalPlaces) | |
.padEnd(decimalPlaces, "0"); | |
return new BN(whole + fractional, 10); | |
} | |
/** | |
* Return a given string if it contains a valid positive decimal number, | |
* otherwise throw a TypeError | |
* @param decimalNumber String representation of a positive decimal number | |
* @param varName Variable name to include in the error message | |
* @throws TypeError | |
* @returns Given string | |
*/ | |
export function ensurePositiveDecimalString( | |
decimalNumber: string, | |
varName = "Given value" | |
): string { | |
if (decimalNumber.startsWith("-")) { | |
throw new TypeError(`${varName} must be positive`); | |
} | |
if (!decimalNumber || !/^\d*(\.\d*)?$/.test(decimalNumber)) { | |
throw new TypeError(`${varName} does not contain a valid decimal number`); | |
} | |
return decimalNumber; | |
} | |
/** | |
* Return a given number if it is a positive integer, otherwise throw a | |
* TypeError | |
* @param num Number | |
* @param varName Variable name to include in the error message | |
* @throws TypeError | |
* @returns Given number | |
*/ | |
export function ensurePositiveInteger( | |
num: number, | |
varName = "Given value" | |
): number { | |
if (!Number.isInteger(num)) { | |
throw new TypeError(`${varName} is not an integer`); | |
} | |
if (num < 0) { | |
throw new TypeError(`${varName} must be positive`); | |
} | |
return num; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment