@@ -865,10 +865,24 @@ interface FullySpecifiedConstructorOptions {
865
865
normalize : boolean ;
866
866
}
867
867
868
- const DEFAULT_CONSTRUCTOR_OPTIONS : FullySpecifiedConstructorOptions = {
869
- roundingMode : ROUNDING_MODE_DEFAULT ,
870
- normalize : CONSTRUCTOR_SHOULD_NORMALIZE ,
871
- } ;
868
+ const DEFAULT_CONSTRUCTOR_OPTIONS : FullySpecifiedConstructorOptions =
869
+ Object . freeze ( {
870
+ roundingMode : ROUNDING_MODE_DEFAULT ,
871
+ normalize : CONSTRUCTOR_SHOULD_NORMALIZE ,
872
+ } ) ;
873
+
874
+ interface ArithmeticOperationOptions {
875
+ roundingMode ?: RoundingMode ;
876
+ }
877
+
878
+ interface FullySpecifiedArithmeticOperationOptions {
879
+ roundingMode : RoundingMode ;
880
+ }
881
+
882
+ const DEFAULT_ARITHMETIC_OPERATION_OPTIONS : FullySpecifiedArithmeticOperationOptions =
883
+ Object . freeze ( {
884
+ roundingMode : ROUNDING_MODE_DEFAULT ,
885
+ } ) ;
872
886
873
887
type ToStringFormat = "decimal" | "exponential" ;
874
888
const TOSTRING_FORMATS : string [ ] = [ "decimal" , "exponential" ] ;
@@ -883,10 +897,10 @@ interface FullySpecifiedToStringOptions {
883
897
numDecimalDigits : number | undefined ;
884
898
}
885
899
886
- const DEFAULT_TOSTRING_OPTIONS : FullySpecifiedToStringOptions = {
900
+ const DEFAULT_TOSTRING_OPTIONS : FullySpecifiedToStringOptions = Object . freeze ( {
887
901
format : "decimal" ,
888
902
numDecimalDigits : undefined ,
889
- } ;
903
+ } ) ;
890
904
891
905
function ensureFullySpecifiedConstructorOptions (
892
906
options ?: ConstructorOptions
@@ -911,6 +925,25 @@ function ensureFullySpecifiedConstructorOptions(
911
925
return opts ;
912
926
}
913
927
928
+ function ensureFullySpecifiedArithmeticOperationOptions (
929
+ options ?: ArithmeticOperationOptions
930
+ ) : FullySpecifiedArithmeticOperationOptions {
931
+ let opts = { ...DEFAULT_ARITHMETIC_OPERATION_OPTIONS } ;
932
+
933
+ if ( undefined === options ) {
934
+ return opts ;
935
+ }
936
+
937
+ if (
938
+ "string" === typeof options . roundingMode &&
939
+ ROUNDING_MODES . includes ( options . roundingMode )
940
+ ) {
941
+ opts . roundingMode = options . roundingMode ;
942
+ }
943
+
944
+ return opts ;
945
+ }
946
+
914
947
function ensureFullySpecifiedToStringOptions (
915
948
options ?: ToStringOptions
916
949
) : FullySpecifiedToStringOptions {
@@ -1144,8 +1177,9 @@ export class Decimal128 {
1144
1177
* Add this Decimal128 value to one or more Decimal128 values.
1145
1178
*
1146
1179
* @param x
1180
+ * @param opts
1147
1181
*/
1148
- add ( x : Decimal128 ) : Decimal128 {
1182
+ add ( x : Decimal128 , opts ?: ArithmeticOperationOptions ) : Decimal128 {
1149
1183
if ( this . isNaN ( ) || x . isNaN ( ) ) {
1150
1184
return new Decimal128 ( NAN ) ;
1151
1185
}
@@ -1167,12 +1201,14 @@ export class Decimal128 {
1167
1201
}
1168
1202
1169
1203
if ( this . isNegative && x . isNegative ) {
1170
- return this . negate ( ) . add ( x . negate ( ) ) . negate ( ) ;
1204
+ return this . negate ( ) . add ( x . negate ( ) , opts ) . negate ( ) ;
1171
1205
}
1172
1206
1173
1207
let resultRat = Rational . add ( this . rat , x . rat ) ;
1208
+ let options = ensureFullySpecifiedArithmeticOperationOptions ( opts ) ;
1174
1209
let initialResult = new Decimal128 (
1175
- resultRat . toDecimalPlaces ( MAX_SIGNIFICANT_DIGITS + 1 )
1210
+ resultRat . toDecimalPlaces ( MAX_SIGNIFICANT_DIGITS + 1 ) ,
1211
+ { roundingMode : options . roundingMode }
1176
1212
) ;
1177
1213
let adjusted = initialResult . setExponent (
1178
1214
Math . min ( this . exponent , x . exponent )
@@ -1185,8 +1221,9 @@ export class Decimal128 {
1185
1221
* Subtract another Decimal128 value from one or more Decimal128 values.
1186
1222
*
1187
1223
* @param x
1224
+ * @param opts
1188
1225
*/
1189
- subtract ( x : Decimal128 ) : Decimal128 {
1226
+ subtract ( x : Decimal128 , opts ?: ArithmeticOperationOptions ) : Decimal128 {
1190
1227
if ( this . isNaN ( ) || x . isNaN ( ) ) {
1191
1228
return new Decimal128 ( NAN ) ;
1192
1229
}
@@ -1215,7 +1252,9 @@ export class Decimal128 {
1215
1252
MAX_SIGNIFICANT_DIGITS + 1
1216
1253
) ;
1217
1254
1218
- let initialResult = new Decimal128 ( rendered ) ;
1255
+ let options = ensureFullySpecifiedArithmeticOperationOptions ( opts ) ;
1256
+
1257
+ let initialResult = new Decimal128 ( rendered , options ) ;
1219
1258
let adjusted = initialResult . setExponent (
1220
1259
Math . min ( this . exponent , x . exponent )
1221
1260
) ;
@@ -1228,8 +1267,9 @@ export class Decimal128 {
1228
1267
* If no arguments are given, return this value.
1229
1268
*
1230
1269
* @param x
1270
+ * @param opts
1231
1271
*/
1232
- multiply ( x : Decimal128 ) : Decimal128 {
1272
+ multiply ( x : Decimal128 , opts ?: ArithmeticOperationOptions ) : Decimal128 {
1233
1273
if ( this . isNaN ( ) || x . isNaN ( ) ) {
1234
1274
return new Decimal128 ( NAN ) ;
1235
1275
}
@@ -1268,7 +1308,8 @@ export class Decimal128 {
1268
1308
1269
1309
let resultRat = Rational . multiply ( this . rat , x . rat ) ;
1270
1310
let initialResult = new Decimal128 (
1271
- resultRat . toDecimalPlaces ( MAX_SIGNIFICANT_DIGITS + 1 )
1311
+ resultRat . toDecimalPlaces ( MAX_SIGNIFICANT_DIGITS + 1 ) ,
1312
+ ensureFullySpecifiedArithmeticOperationOptions ( opts )
1272
1313
) ;
1273
1314
let adjusted = initialResult . setExponent ( this . exponent + x . exponent ) ;
1274
1315
@@ -1291,8 +1332,9 @@ export class Decimal128 {
1291
1332
* If only one argument is given, just return the first argument.
1292
1333
*
1293
1334
* @param x
1335
+ * @param opts
1294
1336
*/
1295
- divide ( x : Decimal128 ) : Decimal128 {
1337
+ divide ( x : Decimal128 , opts ?: ArithmeticOperationOptions ) : Decimal128 {
1296
1338
if ( this . isNaN ( ) || x . isNaN ( ) ) {
1297
1339
return new Decimal128 ( NAN ) ;
1298
1340
}
@@ -1375,7 +1417,10 @@ export class Decimal128 {
1375
1417
}
1376
1418
1377
1419
let resultExponent = this . exponent - ( x . exponent + adjust ) ;
1378
- return new Decimal128 ( `${ resultCoefficient } E${ resultExponent } ` ) ;
1420
+ return new Decimal128 (
1421
+ `${ resultCoefficient } E${ resultExponent } ` ,
1422
+ ensureFullySpecifiedArithmeticOperationOptions ( opts )
1423
+ ) ;
1379
1424
}
1380
1425
1381
1426
/**
@@ -1453,9 +1498,10 @@ export class Decimal128 {
1453
1498
* Return the remainder of this Decimal128 value divided by another Decimal128 value.
1454
1499
*
1455
1500
* @param d
1501
+ * @param opts
1456
1502
* @throws RangeError If argument is zero
1457
1503
*/
1458
- remainder ( d : Decimal128 ) : Decimal128 {
1504
+ remainder ( d : Decimal128 , opts ?: ArithmeticOperationOptions ) : Decimal128 {
1459
1505
if ( this . isNaN ( ) || d . isNaN ( ) ) {
1460
1506
return new Decimal128 ( NAN ) ;
1461
1507
}
@@ -1481,7 +1527,7 @@ export class Decimal128 {
1481
1527
}
1482
1528
1483
1529
let q = this . divide ( d ) . round ( 0 , ROUNDING_MODE_TRUNCATE ) ;
1484
- return this . subtract ( d . multiply ( q ) ) ;
1530
+ return this . subtract ( d . multiply ( q ) , opts ) ;
1485
1531
}
1486
1532
1487
1533
normalize ( ) : Decimal128 {
0 commit comments