@ckb-lumos/bi
Advanced tools
Comparing version 0.19.0-beta.0 to 0.19.0
@@ -37,1 +37,6 @@ import JSBI from "jsbi"; | ||
export declare function toJSBI(value: BIish): JSBI; | ||
export declare type Unit = "shannon" | "ckb" | number; | ||
export declare const ckbDecimals = 8; | ||
export declare function formatUnit(value: BIish, unit: Unit): string; | ||
export declare function parseUnit(value: string, unit: Unit): BI; | ||
//# sourceMappingURL=index.d.ts.map |
148
lib/index.js
@@ -6,4 +6,6 @@ "use strict"; | ||
}); | ||
exports.BI = void 0; | ||
exports.ckbDecimals = exports.BI = void 0; | ||
exports.formatUnit = formatUnit; | ||
exports.isBIish = isBIish; | ||
exports.parseUnit = parseUnit; | ||
exports.toJSBI = toJSBI; | ||
@@ -188,2 +190,146 @@ | ||
} | ||
const validUnitNames = ["shannon", "ckb"]; | ||
const ckbDecimals = 8; | ||
exports.ckbDecimals = ckbDecimals; | ||
const negativeOne = BI.from(-1); | ||
function formatUnit(value, unit) { | ||
const decimals = parseDecimals(unit); | ||
return formatFixed(value, decimals); | ||
} | ||
function parseUnit(value, unit) { | ||
const decimals = parseDecimals(unit); | ||
return parseFixed(value, decimals); | ||
} | ||
function formatFixed(value, decimals) { | ||
if (!isValidDecimalSize(decimals)) { | ||
throw new Error(`decimal size must be a non-negative integer`); | ||
} | ||
const multiplier = "1" + Array(decimals).fill("0").join(""); | ||
value = BI.from(value); | ||
const isNegative = value.isNegative(); | ||
if (isNegative) { | ||
value = value.mul(negativeOne); | ||
} | ||
const wholePart = value.div(multiplier).toString(); | ||
let result = wholePart; | ||
if (multiplier.length > 1) { | ||
let decimalPart = value.mod(multiplier).toString(); | ||
while (decimalPart.length < multiplier.length - 1) { | ||
decimalPart = "0" + decimalPart; | ||
} // remove trailing zeros | ||
decimalPart = decimalPart.match(/^([0-9]*[1-9]|0)(0*)/)[1]; | ||
result += "." + decimalPart; | ||
} | ||
if (isNegative) { | ||
result = "-" + result; | ||
} | ||
return result; | ||
} | ||
function parseFixed(value, decimals) { | ||
if (!isValidDecimalSize(decimals)) { | ||
throw new Error(`decimal size must be a non-negative integer`); | ||
} // check if value represents a valid decimal number | ||
if (!value.match(/^-?\d+(\.\d{1,})?$/)) { | ||
throw new Error("invalid decimal string"); | ||
} | ||
const multiplier = "1" + Array(decimals).fill("0").join(""); | ||
const isNegative = value.substring(0, 1) === "-"; | ||
if (isNegative) { | ||
value = value.substring(1); | ||
} | ||
let wholePart, decimalPart; | ||
const valueParts = value.split("."); | ||
if (valueParts.length === 1) { | ||
wholePart = valueParts[0]; | ||
decimalPart = "0"; | ||
} else if (valueParts.length === 2) { | ||
wholePart = valueParts[0]; | ||
decimalPart = valueParts[1]; | ||
} else { | ||
throw new Error("too many decimal points (should not happen)"); | ||
} // remove leading zeros of whole part | ||
while (wholePart.length > 0 && wholePart[0] === "0") { | ||
wholePart = wholePart.substring(1); | ||
} | ||
if (wholePart === "") { | ||
wholePart = "0"; | ||
} // remove trailing zeros of decimal part | ||
while (decimalPart.length > 0 && decimalPart[decimalPart.length - 1] === "0") { | ||
decimalPart = decimalPart.substring(0, decimalPart.length - 1); | ||
} | ||
if (decimalPart.length > multiplier.length - 1) { | ||
throw new Error("decimal part exceeds max decimals"); | ||
} | ||
if (decimalPart === "") { | ||
decimalPart = "0"; | ||
} // pad decimal part with zeros to get to shannon | ||
while (decimalPart.length < multiplier.length - 1) { | ||
decimalPart += "0"; | ||
} | ||
const wholeValue = BI.from(wholePart); | ||
const decimalValue = BI.from(decimalPart); | ||
let shannons = wholeValue.mul(multiplier).add(decimalValue); | ||
if (isNegative) { | ||
shannons = shannons.mul(negativeOne); | ||
} | ||
return shannons; | ||
} | ||
function parseDecimals(unit) { | ||
let decimals = 0; | ||
if (typeof unit === "string") { | ||
if (validUnitNames.indexOf(unit) === -1) { | ||
throw new Error(`invalid unit name, supported names are ${validUnitNames.join(", ")}`); | ||
} | ||
if (unit === "ckb") { | ||
decimals = ckbDecimals; | ||
} | ||
} else { | ||
if (isValidDecimalSize(unit)) { | ||
decimals = unit; | ||
} else { | ||
throw new Error(`unit of integer must be a non-negative integer`); | ||
} | ||
} | ||
return decimals; | ||
} | ||
function isValidDecimalSize(decimals) { | ||
return Number.isInteger(decimals) && decimals >= 0; | ||
} | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@ckb-lumos/bi", | ||
"version": "0.19.0-beta.0", | ||
"version": "0.19.0", | ||
"description": "Bigint support in lumos", | ||
@@ -53,3 +53,3 @@ "author": "", | ||
}, | ||
"gitHead": "6f7065672f047445f109385a8bf56fe42d8d5f91" | ||
"gitHead": "ce18d6d2b15793e61e0e35072aa65ebe4aea5b55" | ||
} |
143
src/index.ts
@@ -188,1 +188,144 @@ import JSBI from "jsbi"; | ||
} | ||
export type Unit = "shannon" | "ckb" | number; | ||
const validUnitNames = ["shannon", "ckb"]; | ||
export const ckbDecimals = 8; | ||
const negativeOne = BI.from(-1); | ||
export function formatUnit(value: BIish, unit: Unit): string { | ||
const decimals = parseDecimals(unit); | ||
return formatFixed(value, decimals); | ||
} | ||
export function parseUnit(value: string, unit: Unit): BI { | ||
const decimals = parseDecimals(unit); | ||
return parseFixed(value, decimals); | ||
} | ||
function formatFixed(value: BIish, decimals: number): string { | ||
if (!isValidDecimalSize(decimals)) { | ||
throw new Error(`decimal size must be a non-negative integer`); | ||
} | ||
const multiplier = "1" + Array(decimals).fill("0").join(""); | ||
value = BI.from(value); | ||
const isNegative = value.isNegative(); | ||
if (isNegative) { | ||
value = value.mul(negativeOne); | ||
} | ||
const wholePart = value.div(multiplier).toString(); | ||
let result = wholePart; | ||
if (multiplier.length > 1) { | ||
let decimalPart = value.mod(multiplier).toString(); | ||
while (decimalPart.length < multiplier.length - 1) { | ||
decimalPart = "0" + decimalPart; | ||
} | ||
// remove trailing zeros | ||
decimalPart = decimalPart.match(/^([0-9]*[1-9]|0)(0*)/)![1]; | ||
result += "." + decimalPart; | ||
} | ||
if (isNegative) { | ||
result = "-" + result; | ||
} | ||
return result; | ||
} | ||
function parseFixed(value: string, decimals: number): BI { | ||
if (!isValidDecimalSize(decimals)) { | ||
throw new Error(`decimal size must be a non-negative integer`); | ||
} | ||
// check if value represents a valid decimal number | ||
if (!value.match(/^-?\d+(\.\d{1,})?$/)) { | ||
throw new Error("invalid decimal string"); | ||
} | ||
const multiplier = "1" + Array(decimals).fill("0").join(""); | ||
const isNegative = value.substring(0, 1) === "-"; | ||
if (isNegative) { | ||
value = value.substring(1); | ||
} | ||
let wholePart, decimalPart; | ||
const valueParts = value.split("."); | ||
if (valueParts.length === 1) { | ||
wholePart = valueParts[0]; | ||
decimalPart = "0"; | ||
} else if (valueParts.length === 2) { | ||
wholePart = valueParts[0]; | ||
decimalPart = valueParts[1]; | ||
} else { | ||
throw new Error("too many decimal points (should not happen)"); | ||
} | ||
// remove leading zeros of whole part | ||
while (wholePart.length > 0 && wholePart[0] === "0") { | ||
wholePart = wholePart.substring(1); | ||
} | ||
if (wholePart === "") { | ||
wholePart = "0"; | ||
} | ||
// remove trailing zeros of decimal part | ||
while ( | ||
decimalPart.length > 0 && | ||
decimalPart[decimalPart.length - 1] === "0" | ||
) { | ||
decimalPart = decimalPart.substring(0, decimalPart.length - 1); | ||
} | ||
if (decimalPart.length > multiplier.length - 1) { | ||
throw new Error("decimal part exceeds max decimals"); | ||
} | ||
if (decimalPart === "") { | ||
decimalPart = "0"; | ||
} | ||
// pad decimal part with zeros to get to shannon | ||
while (decimalPart.length < multiplier.length - 1) { | ||
decimalPart += "0"; | ||
} | ||
const wholeValue = BI.from(wholePart); | ||
const decimalValue = BI.from(decimalPart); | ||
let shannons = wholeValue.mul(multiplier).add(decimalValue); | ||
if (isNegative) { | ||
shannons = shannons.mul(negativeOne); | ||
} | ||
return shannons; | ||
} | ||
function parseDecimals(unit: Unit): number { | ||
let decimals = 0; | ||
if (typeof unit === "string") { | ||
if (validUnitNames.indexOf(unit) === -1) { | ||
throw new Error( | ||
`invalid unit name, supported names are ${validUnitNames.join(", ")}` | ||
); | ||
} | ||
if (unit === "ckb") { | ||
decimals = ckbDecimals; | ||
} | ||
} else { | ||
if (isValidDecimalSize(unit)) { | ||
decimals = unit; | ||
} else { | ||
throw new Error(`unit of integer must be a non-negative integer`); | ||
} | ||
} | ||
return decimals; | ||
} | ||
function isValidDecimalSize(decimals: number): boolean { | ||
return Number.isInteger(decimals) && decimals >= 0; | ||
} |
Sorry, the diff of this file is not supported yet
40213
8
564