From 7498c18235c7566b2f652cddba991f55e0943da8 Mon Sep 17 00:00:00 2001 From: Richard Moore Date: Wed, 15 Apr 2020 15:39:26 -0400 Subject: [PATCH] Added bitwise operations to BigNumber (#781). --- packages/bignumber/src.ts/bignumber.ts | 53 +++++++++++++++++++++++++- packages/bignumber/thirdparty.d.ts | 10 ++++- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/packages/bignumber/src.ts/bignumber.ts b/packages/bignumber/src.ts/bignumber.ts index 7dde6fd35..39dadedd4 100644 --- a/packages/bignumber/src.ts/bignumber.ts +++ b/packages/bignumber/src.ts/bignumber.ts @@ -89,17 +89,62 @@ export class BigNumber implements Hexable { } mod(other: BigNumberish): BigNumber { - return toBigNumber(toBN(this).mod(toBN(other))); + const value = toBN(other); + if (value.isNeg()) { + throwFault("cannot modulo negative values", "mod"); + } + return toBigNumber(toBN(this).umod(value)); } pow(other: BigNumberish): BigNumber { return toBigNumber(toBN(this).pow(toBN(other))); } - maskn(value: number): BigNumber { + and(other: BigNumberish): BigNumber { + const value = toBN(other); + if (this.isNegative() || value.isNeg()) { + throwFault("cannot 'and' negative values", "and"); + } + return toBigNumber(toBN(this).and(value)); + } + + or(other: BigNumberish): BigNumber { + const value = toBN(other); + if (this.isNegative() || value.isNeg()) { + throwFault("cannot 'or' negative values", "or"); + } + return toBigNumber(toBN(this).or(value)); + } + + xor(other: BigNumberish): BigNumber { + const value = toBN(other); + if (this.isNegative() || value.isNeg()) { + throwFault("cannot 'xor' negative values", "xor"); + } + return toBigNumber(toBN(this).xor(value)); + } + + mask(value: number): BigNumber { + if (this.isNegative() || value < 0) { + throwFault("cannot mask negative values", "mask"); + } return toBigNumber(toBN(this).maskn(value)); } + shl(value: number): BigNumber { + if (this.isNegative() || value < 0) { + throwFault("cannot shift negative values", "shl"); + } + return toBigNumber(toBN(this).shln(value)); + } + + shr(value: number): BigNumber { + if (this.isNegative() || value < 0) { + throwFault("cannot shift negative values", "shr"); + } + return toBigNumber(toBN(this).shrn(value)); + } + eq(other: BigNumberish): boolean { return toBN(this).eq(toBN(other)); } @@ -120,6 +165,10 @@ export class BigNumber implements Hexable { return toBN(this).gte(toBN(other)); } + isNegative(): boolean { + return (this._hex[0] === "-"); + } + isZero(): boolean { return toBN(this).isZero(); } diff --git a/packages/bignumber/thirdparty.d.ts b/packages/bignumber/thirdparty.d.ts index 8c07d6bfb..376001fa4 100644 --- a/packages/bignumber/thirdparty.d.ts +++ b/packages/bignumber/thirdparty.d.ts @@ -9,7 +9,7 @@ declare module "bn.js" { mul(other: BN): BN; pow(other: BN): BN; - maskn(other: number): BN; + umod(other: BN): BN; eq(other: BN): boolean; lt(other: BN): boolean; @@ -17,11 +17,19 @@ declare module "bn.js" { gt(other: BN): boolean; gte(other: BN): boolean; + isNeg(): boolean; isZero(): boolean; toTwos(other: number): BN; fromTwos(other: number): BN; + or(other: BN): BN; + and(other: BN): BN; + xor(other: BN): BN; + shln(other: number): BN; + shrn(other: number): BN; + maskn(other: number): BN; + toString(radix: number): string; toNumber(): number; toArray(endian: string, width: number): Uint8Array;