1- // eslint-disable-next-line @typescript-eslint/naming-convention
2- import BN from "bn.js" ;
3-
41import { Uint32 , Uint53 , Uint64 } from "./integers" ;
52
63// Too large values lead to massive memory usage. Limit to something sensible.
@@ -94,7 +91,7 @@ export class Decimal {
9491
9592 public static compare ( a : Decimal , b : Decimal ) : number {
9693 if ( a . fractionalDigits !== b . fractionalDigits ) throw new Error ( "Fractional digits do not match" ) ;
97- return a . data . atomics . cmp ( new BN ( b . atomics ) ) ;
94+ return Math . sign ( Number ( a . data . atomics - b . data . atomics ) ) ;
9895 }
9996
10097 public get atomics ( ) : string {
@@ -106,7 +103,7 @@ export class Decimal {
106103 }
107104
108105 private readonly data : {
109- readonly atomics : BN ;
106+ readonly atomics : bigint ;
110107 readonly fractionalDigits : number ;
111108 } ;
112109
@@ -118,7 +115,7 @@ export class Decimal {
118115 }
119116
120117 this . data = {
121- atomics : new BN ( atomics ) ,
118+ atomics : BigInt ( atomics ) ,
122119 fractionalDigits : fractionalDigits ,
123120 } ;
124121 }
@@ -130,36 +127,36 @@ export class Decimal {
130127
131128 /** Returns the greatest decimal <= this which has no fractional part (rounding down) */
132129 public floor ( ) : Decimal {
133- const factor = new BN ( 10 ) . pow ( new BN ( this . data . fractionalDigits ) ) ;
134- const whole = this . data . atomics . div ( factor ) ;
135- const fractional = this . data . atomics . mod ( factor ) ;
130+ const factor = 10n ** BigInt ( this . data . fractionalDigits ) ;
131+ const whole = this . data . atomics / factor ;
132+ const fractional = this . data . atomics % factor ;
136133
137- if ( fractional . isZero ( ) ) {
134+ if ( fractional === 0n ) {
138135 return this . clone ( ) ;
139136 } else {
140- return Decimal . fromAtomics ( whole . mul ( factor ) . toString ( ) , this . fractionalDigits ) ;
137+ return Decimal . fromAtomics ( ( whole * factor ) . toString ( ) , this . fractionalDigits ) ;
141138 }
142139 }
143140
144141 /** Returns the smallest decimal >= this which has no fractional part (rounding up) */
145142 public ceil ( ) : Decimal {
146- const factor = new BN ( 10 ) . pow ( new BN ( this . data . fractionalDigits ) ) ;
147- const whole = this . data . atomics . div ( factor ) ;
148- const fractional = this . data . atomics . mod ( factor ) ;
143+ const factor = 10n ** BigInt ( this . data . fractionalDigits ) ;
144+ const whole = this . data . atomics / factor ;
145+ const fractional = this . data . atomics % factor ;
149146
150- if ( fractional . isZero ( ) ) {
147+ if ( fractional === 0n ) {
151148 return this . clone ( ) ;
152149 } else {
153- return Decimal . fromAtomics ( whole . addn ( 1 ) . mul ( factor ) . toString ( ) , this . fractionalDigits ) ;
150+ return Decimal . fromAtomics ( ( ( whole + 1n ) * factor ) . toString ( ) , this . fractionalDigits ) ;
154151 }
155152 }
156153
157154 public toString ( ) : string {
158- const factor = new BN ( 10 ) . pow ( new BN ( this . data . fractionalDigits ) ) ;
159- const whole = this . data . atomics . div ( factor ) ;
160- const fractional = this . data . atomics . mod ( factor ) ;
155+ const factor = 10n ** BigInt ( this . data . fractionalDigits ) ;
156+ const whole = this . data . atomics / factor ;
157+ const fractional = this . data . atomics % factor ;
161158
162- if ( fractional . isZero ( ) ) {
159+ if ( fractional === 0n ) {
163160 return whole . toString ( ) ;
164161 } else {
165162 const fullFractionalPart = fractional . toString ( ) . padStart ( this . data . fractionalDigits , "0" ) ;
@@ -185,7 +182,7 @@ export class Decimal {
185182 */
186183 public plus ( b : Decimal ) : Decimal {
187184 if ( this . fractionalDigits !== b . fractionalDigits ) throw new Error ( "Fractional digits do not match" ) ;
188- const sum = this . data . atomics . add ( new BN ( b . atomics ) ) ;
185+ const sum = this . data . atomics + b . data . atomics ;
189186 return new Decimal ( sum . toString ( ) , this . fractionalDigits ) ;
190187 }
191188
@@ -197,8 +194,8 @@ export class Decimal {
197194 */
198195 public minus ( b : Decimal ) : Decimal {
199196 if ( this . fractionalDigits !== b . fractionalDigits ) throw new Error ( "Fractional digits do not match" ) ;
200- const difference = this . data . atomics . sub ( new BN ( b . atomics ) ) ;
201- if ( difference . ltn ( 0 ) ) throw new Error ( "Difference must not be negative" ) ;
197+ const difference = this . data . atomics - b . data . atomics ;
198+ if ( difference < 0n ) throw new Error ( "Difference must not be negative" ) ;
202199 return new Decimal ( difference . toString ( ) , this . fractionalDigits ) ;
203200 }
204201
@@ -208,7 +205,7 @@ export class Decimal {
208205 * We only allow multiplication by unsigned integers to avoid rounding errors.
209206 */
210207 public multiply ( b : Uint32 | Uint53 | Uint64 ) : Decimal {
211- const product = this . data . atomics . mul ( new BN ( b . toString ( ) ) ) ;
208+ const product = this . data . atomics * b . toBigInt ( ) ;
212209 return new Decimal ( product . toString ( ) , this . fractionalDigits ) ;
213210 }
214211
0 commit comments