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,10 @@ 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+ const difference = a . data . atomics - b . data . atomics ;
95+ if ( difference < 0n ) return - 1 ;
96+ if ( difference > 0n ) return 1 ;
97+ return 0 ;
9898 }
9999
100100 public get atomics ( ) : string {
@@ -106,7 +106,7 @@ export class Decimal {
106106 }
107107
108108 private readonly data : {
109- readonly atomics : BN ;
109+ readonly atomics : bigint ;
110110 readonly fractionalDigits : number ;
111111 } ;
112112
@@ -118,7 +118,7 @@ export class Decimal {
118118 }
119119
120120 this . data = {
121- atomics : new BN ( atomics ) ,
121+ atomics : BigInt ( atomics ) ,
122122 fractionalDigits : fractionalDigits ,
123123 } ;
124124 }
@@ -130,36 +130,36 @@ export class Decimal {
130130
131131 /** Returns the greatest decimal <= this which has no fractional part (rounding down) */
132132 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 ) ;
133+ const factor = 10n ** BigInt ( this . data . fractionalDigits ) ;
134+ const whole = this . data . atomics / factor ;
135+ const fractional = this . data . atomics % factor ;
136136
137- if ( fractional . isZero ( ) ) {
137+ if ( fractional === 0n ) {
138138 return this . clone ( ) ;
139139 } else {
140- return Decimal . fromAtomics ( whole . mul ( factor ) . toString ( ) , this . fractionalDigits ) ;
140+ return Decimal . fromAtomics ( ( whole * factor ) . toString ( ) , this . fractionalDigits ) ;
141141 }
142142 }
143143
144144 /** Returns the smallest decimal >= this which has no fractional part (rounding up) */
145145 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 ) ;
146+ const factor = 10n ** BigInt ( this . data . fractionalDigits ) ;
147+ const whole = this . data . atomics / factor ;
148+ const fractional = this . data . atomics % factor ;
149149
150- if ( fractional . isZero ( ) ) {
150+ if ( fractional === 0n ) {
151151 return this . clone ( ) ;
152152 } else {
153- return Decimal . fromAtomics ( whole . addn ( 1 ) . mul ( factor ) . toString ( ) , this . fractionalDigits ) ;
153+ return Decimal . fromAtomics ( ( ( whole + 1n ) * factor ) . toString ( ) , this . fractionalDigits ) ;
154154 }
155155 }
156156
157157 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 ) ;
158+ const factor = 10n ** BigInt ( this . data . fractionalDigits ) ;
159+ const whole = this . data . atomics / factor ;
160+ const fractional = this . data . atomics % factor ;
161161
162- if ( fractional . isZero ( ) ) {
162+ if ( fractional === 0n ) {
163163 return whole . toString ( ) ;
164164 } else {
165165 const fullFractionalPart = fractional . toString ( ) . padStart ( this . data . fractionalDigits , "0" ) ;
@@ -185,7 +185,7 @@ export class Decimal {
185185 */
186186 public plus ( b : Decimal ) : Decimal {
187187 if ( this . fractionalDigits !== b . fractionalDigits ) throw new Error ( "Fractional digits do not match" ) ;
188- const sum = this . data . atomics . add ( new BN ( b . atomics ) ) ;
188+ const sum = this . data . atomics + b . data . atomics ;
189189 return new Decimal ( sum . toString ( ) , this . fractionalDigits ) ;
190190 }
191191
@@ -197,8 +197,8 @@ export class Decimal {
197197 */
198198 public minus ( b : Decimal ) : Decimal {
199199 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" ) ;
200+ const difference = this . data . atomics - b . data . atomics ;
201+ if ( difference < 0n ) throw new Error ( "Difference must not be negative" ) ;
202202 return new Decimal ( difference . toString ( ) , this . fractionalDigits ) ;
203203 }
204204
@@ -208,7 +208,7 @@ export class Decimal {
208208 * We only allow multiplication by unsigned integers to avoid rounding errors.
209209 */
210210 public multiply ( b : Uint32 | Uint53 | Uint64 ) : Decimal {
211- const product = this . data . atomics . mul ( new BN ( b . toString ( ) ) ) ;
211+ const product = this . data . atomics * b . toBigInt ( ) ;
212212 return new Decimal ( product . toString ( ) , this . fractionalDigits ) ;
213213 }
214214
0 commit comments