Skip to content
Open
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
3 changes: 0 additions & 3 deletions .babelrc

This file was deleted.

11 changes: 0 additions & 11 deletions .circleci/config.yml

This file was deleted.

3 changes: 1 addition & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"extends": [
"standard-kit/prettier",
"standard-kit/prettier/node",
"standard-kit/prettier/jsx",
"standard-kit/prettier/typescript"
],
"parserOptions": {
Expand All @@ -11,7 +10,7 @@
"plugins": ["simple-import-sort"],
"rules": {
"no-dupe-class-members": 0,
"simple-import-sort/sort": "error",
"simple-import-sort/imports": "error",
"@typescript-eslint/no-floating-promises": 0,
"@typescript-eslint/no-misused-promises": 0,
"@typescript-eslint/promise-function-async": 0,
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,7 @@ typings/
.idea/

# Libs
lib/
lib/

# AI
.claude
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
language: node_js
sudo: false
node_js:
- "8.4"
- "18"
install:
- npm i -d
script:
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## Unreleased

## 5.0.0 (unreleased)

- changed: Replace `bn.js` dependency with native `BigInt`. Now requires Node.js >= 10.4.
- changed: Bump TypeScript target to ES2020.

## 4.2.3 (2024-07-16)

- fixed: Treat '.' as zero
Expand Down
30 changes: 12 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "biggystring",
"version": "4.2.3",
"version": "5.0.0",
"description": "Full floating point big number library using regular Javascript string",
"keywords": [
"big",
Expand All @@ -20,6 +20,9 @@
],
"types": "./lib/src/index.d.ts",
"main": "./lib/src/index.js",
"engines": {
"node": ">=10.4"
},
"files": [
"lib/*",
"package.json",
Expand All @@ -28,7 +31,7 @@
"scripts": {
"build": "tsc",
"cover": "nyc --reporter=lcov --reporter=text --reporter=html --extension .js npm test",
"lint": "eslint --ext .js,.jsx,.ts,.tsx ./src",
"lint": "eslint --ext .ts ./src",
"fix": "npm run lint -- --fix",
"precommit": "lint-staged && npm run build && npm test",
"prepare": "husky install && npm run build",
Expand All @@ -37,35 +40,26 @@
"lint-staged": {
"*.{js,ts}": "eslint"
},
"dependencies": {
"bn.js": "^4.11.7"
},
"devDependencies": {
"@types/bn.js": "^4.11.6",
"@types/chai": "^4.3.4",
"@types/mocha": "^10.0.1",
"@types/node": "^14.0.23",
"@typescript-eslint/eslint-plugin": ">=2.0.0",
"@typescript-eslint/parser": "^2.0.0",
"babel-cli": "^6.24.1",
"babel-eslint": "^7.2.3",
"@types/node": "^18.19.0",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"chai": "^4.3.7",
"eslint": ">=6.2.2",
"eslint-config-standard-kit": ">=0.14.4",
"eslint": "^7.32.0",
"eslint-config-standard-kit": "^0.14.4",
"eslint-plugin-import": ">=2.18.0",
"eslint-plugin-json-files": "^1.4.0",
"eslint-plugin-node": ">=9.1.0",
"eslint-plugin-prettier": ">=3.0.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-promise": ">=4.2.1",
"eslint-plugin-react": ">=7.14.2",
"eslint-plugin-simple-import-sort": ">=4.0.0",
"eslint-plugin-standard": ">=4.0.0",
"husky": "^8.0.2",
"lint-staged": "^13.1.0",
"mocha": "^10.1.0",
"prettier": "^2.0.5",
"sucrase": "^3.12.1",
"ts-node": "^8.6.2",
"typescript": "^3.8.2"
"typescript": "5.0.4"
}
}
155 changes: 52 additions & 103 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
* Created by paul on 7/25/17.
*/

import BN from 'bn.js'

interface ShiftPair {
shift: number
x: string
Expand All @@ -22,14 +20,11 @@ export function add(
base: number = 10
): string {
if (base !== 10 && base !== 16) throw new Error('Unsupported base')
let { x, y, shift } = floatShifts(x1, y1)
const xBase = isHex(x) ? 16 : 10
const yBase = isHex(y) ? 16 : 10
x = cropHex(x)
y = cropHex(y)
const xBN = new BN(x, xBase)
const yBN = new BN(y, yBase)
let out = xBN.add(yBN).toString(base)
const { x, y, shift } = floatShifts(x1, y1)
const xBig = parseBigInt(x)
const yBig = parseBigInt(y)
const result = xBig + yBig
let out = result.toString(base)
out = addDecimal(out, shift)
return base === 10 ? out : out.replace(/^(-)?/, '$10x')
}
Expand All @@ -40,14 +35,11 @@ export function mul(
base: number = 10
): string {
if (base !== 10 && base !== 16) throw new Error('Unsupported base')
let { x, y, shift } = floatShifts(x1, y1)
const xBase = isHex(x) ? 16 : 10
const yBase = isHex(y) ? 16 : 10
x = cropHex(x)
y = cropHex(y)
const xBN = new BN(x, xBase)
const yBN = new BN(y, yBase)
let out = xBN.mul(yBN).toString(base)
const { x, y, shift } = floatShifts(x1, y1)
const xBig = parseBigInt(x)
const yBig = parseBigInt(y)
const result = xBig * yBig
let out = result.toString(base)
out = addDecimal(out, shift * 2)
return base === 10 ? out : out.replace(/^(-)?/, '$10x')
}
Expand All @@ -58,14 +50,11 @@ export function sub(
base: number = 10
): string {
if (base !== 10 && base !== 16) throw new Error('Unsupported base')
let { x, y, shift } = floatShifts(x1, y1)
const xBase = isHex(x) ? 16 : 10
const yBase = isHex(y) ? 16 : 10
x = cropHex(x)
y = cropHex(y)
const xBN = new BN(x, xBase)
const yBN = new BN(y, yBase)
let out = xBN.sub(yBN).toString(base)
const { x, y, shift } = floatShifts(x1, y1)
const xBig = parseBigInt(x)
const yBig = parseBigInt(y)
const result = xBig - yBig
let out = result.toString(base)
out = addDecimal(out, shift)
return base === 10 ? out : out.replace(/^(-)?/, '$10x')
}
Expand All @@ -80,102 +69,64 @@ export function div(
throw new Error('Cannot operate on floating point hex values')
}
if (base !== 10 && base !== 16) throw new Error('Unsupported base')
let { x, y } = floatShifts(x1, y1, precision)
const xBase = isHex(x) ? 16 : 10
const yBase = isHex(y) ? 16 : 10
x = cropHex(x)
y = cropHex(y)
const xBN = new BN(x, xBase)
const yBN = new BN(y, yBase)
let out = xBN.div(yBN).toString(base)
const { x, y } = floatShifts(x1, y1, precision)
const xBig = parseBigInt(x)
const yBig = parseBigInt(y)
const result = xBig / yBig
let out = result.toString(base)
out = addDecimal(out, precision)
return base === 10 ? out : out.replace(/^(-)?/, '$10x')
}

export function lt(x1: string | number, y1: string | number): boolean {
let { x, y } = floatShifts(x1, y1)
const xBase = isHex(x) ? 16 : 10
const yBase = isHex(y) ? 16 : 10
x = cropHex(x)
y = cropHex(y)
const xBN = new BN(x, xBase)
const yBN = new BN(y, yBase)
return xBN.lt(yBN)
const { x, y } = floatShifts(x1, y1)
return parseBigInt(x) < parseBigInt(y)
}

export function lte(x1: string | number, y1: string | number): boolean {
let { x, y } = floatShifts(x1, y1)
const xBase = isHex(x) ? 16 : 10
const yBase = isHex(y) ? 16 : 10
x = cropHex(x)
y = cropHex(y)
const xBN = new BN(x, xBase)
const yBN = new BN(y, yBase)
return xBN.lte(yBN)
const { x, y } = floatShifts(x1, y1)
return parseBigInt(x) <= parseBigInt(y)
}

export function gt(x1: string | number, y1: string | number): boolean {
let { x, y } = floatShifts(x1, y1)
const xBase = isHex(x) ? 16 : 10
const yBase = isHex(y) ? 16 : 10
x = cropHex(x)
y = cropHex(y)
const xBN = new BN(x, xBase)
const yBN = new BN(y, yBase)
return xBN.gt(yBN)
const { x, y } = floatShifts(x1, y1)
return parseBigInt(x) > parseBigInt(y)
}

export function gte(x1: string | number, y1: string | number): boolean {
let { x, y } = floatShifts(x1, y1)
const xBase = isHex(x) ? 16 : 10
const yBase = isHex(y) ? 16 : 10
x = cropHex(x)
y = cropHex(y)
const xBN = new BN(x, xBase)
const yBN = new BN(y, yBase)
return xBN.gte(yBN)
const { x, y } = floatShifts(x1, y1)
return parseBigInt(x) >= parseBigInt(y)
}

export function eq(x1: string | number, y1: string | number): boolean {
let { x, y } = floatShifts(x1, y1)
const xBase = isHex(x) ? 16 : 10
const yBase = isHex(y) ? 16 : 10
x = cropHex(x)
y = cropHex(y)
const xBN = new BN(x, xBase)
const yBN = new BN(y, yBase)
return xBN.eq(yBN)
const { x, y } = floatShifts(x1, y1)
return parseBigInt(x) === parseBigInt(y)
}

export function min(
x1: string | number,
y1: string | number,
base: number = 10
): string {
let { x, y, shift } = floatShifts(x1, y1)
const xBase = isHex(x) ? 16 : 10
const yBase = isHex(y) ? 16 : 10
x = cropHex(x)
y = cropHex(y)
const xBN = new BN(x, xBase)
const yBN = new BN(y, yBase)
const { x, y, shift } = floatShifts(x1, y1)
const xBig = parseBigInt(x)
const yBig = parseBigInt(y)
let out
if (xBN.lte(yBN)) {
out = xBN.toString(base)
if (xBig <= yBig) {
out = xBig.toString(base)
} else {
out = yBN.toString(base)
out = yBig.toString(base)
}
out = addDecimal(out, shift)
return base === 10 ? out : out.replace(/^(-)?/, '$10x')
}

export function abs(x1: string | number, base: number = 10): string {
if (base !== 10 && base !== 16) throw new Error('Unsupported base')
let { x, shift } = floatShifts(x1, '0')
const xBase = isHex(x1) ? 16 : 10
x = cropHex(x)
const xBN = new BN(x, xBase)
let out = xBN.abs().toString(base)
const { x, shift } = floatShifts(x1, '0')
const xBig = parseBigInt(x)
const absBig = xBig < 0n ? -xBig : xBig
let out = absBig.toString(base)
out = addDecimal(out, shift)
return base === 10 ? out : out.replace(/^(-)?/, '$10x')
}
Expand All @@ -185,18 +136,14 @@ export function max(
y1: string | number,
base: number = 10
): string {
let { x, y, shift } = floatShifts(x1, y1)
const xBase = isHex(x) ? 16 : 10
const yBase = isHex(y) ? 16 : 10
x = cropHex(x)
y = cropHex(y)
const xBN = new BN(x, xBase)
const yBN = new BN(y, yBase)
const { x, y, shift } = floatShifts(x1, y1)
const xBig = parseBigInt(x)
const yBig = parseBigInt(y)
let out
if (xBN.gte(yBN)) {
out = xBN.toString(base)
if (xBig >= yBig) {
out = xBig.toString(base)
} else {
out = yBN.toString(base)
out = yBig.toString(base)
}
out = addDecimal(out, shift)
return base === 10 ? out : out.replace(/^(-)?/, '$10x')
Expand Down Expand Up @@ -289,6 +236,12 @@ export function log10(x: string): number {
// Private
// -----------------------------------------------------------------------------

// BigInt() throws on signed non-decimal literals like '-0x100' because the
// spec's StringIntegerLiteral grammar only allows a sign on decimal numerals.
// Strip a leading '-' and re-apply it after parsing so hex inputs work.
const parseBigInt = (value: string): bigint =>
value.startsWith('-') ? -BigInt(value.slice(1)) : BigInt(value)

function addDecimal(x: string, shift: number): string {
if (shift === 0) return x
let isNegative = false
Expand Down Expand Up @@ -318,10 +271,6 @@ function addZeros(val: string, numZeros: number): string {
return out
}

function cropHex(x: string): string {
return x.replace('0x', '')
}

// Takes two floating point (base 10) numbers and finds the multiplier needed to make them both
// operable as a integer
function floatShifts(
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"module": "commonjs",
"moduleResolution": "node",
"resolveJsonModule": true,
"target": "es2017",
"target": "es2020",
"strict": true
},
"include": ["src", "test"],
Expand Down
Loading
Loading