@@ -333,7 +333,9 @@ function roundHalfEven(
333
333
} ;
334
334
}
335
335
336
- function roundCeiling ( x : SignedSignificandExponent ) : SignedSignificandExponent {
336
+ function roundHalfExpand (
337
+ x : SignedSignificandExponent
338
+ ) : SignedSignificandExponent {
337
339
let sig = x . significand . toString ( ) ;
338
340
let lastDigit = parseInt ( sig . charAt ( MAX_SIGNIFICANT_DIGITS ) ) as Digit ;
339
341
let cutoff = cutoffAfterSignificantDigits ( sig , MAX_SIGNIFICANT_DIGITS - 1 ) ;
@@ -348,17 +350,27 @@ function roundCeiling(x: SignedSignificandExponent): SignedSignificandExponent {
348
350
x . isNegative ,
349
351
penultimateDigit ,
350
352
lastDigit ,
351
- ROUNDING_MODE_CEILING
353
+ ROUNDING_MODE_HALF_EXPAND
352
354
) ;
353
355
356
+ if ( finalDigit < 10 ) {
357
+ return {
358
+ isNegative : x . isNegative ,
359
+ significand : BigInt ( `${ cutoff } ${ finalDigit } ` ) ,
360
+ exponent : exp ,
361
+ } ;
362
+ }
363
+
364
+ let rounded = propagateCarryFromRight ( cutoff ) ;
365
+
354
366
return {
355
367
isNegative : x . isNegative ,
356
- significand : BigInt ( `${ cutoff } ${ finalDigit } ` ) ,
368
+ significand : BigInt ( `${ rounded } 0 ` ) ,
357
369
exponent : exp ,
358
370
} ;
359
371
}
360
372
361
- function roundFloor ( x : SignedSignificandExponent ) : SignedSignificandExponent {
373
+ function roundCeiling ( x : SignedSignificandExponent ) : SignedSignificandExponent {
362
374
let sig = x . significand . toString ( ) ;
363
375
let lastDigit = parseInt ( sig . charAt ( MAX_SIGNIFICANT_DIGITS ) ) as Digit ;
364
376
let cutoff = cutoffAfterSignificantDigits ( sig , MAX_SIGNIFICANT_DIGITS - 1 ) ;
@@ -373,27 +385,17 @@ function roundFloor(x: SignedSignificandExponent): SignedSignificandExponent {
373
385
x . isNegative ,
374
386
penultimateDigit ,
375
387
lastDigit ,
376
- ROUNDING_MODE_FLOOR
388
+ ROUNDING_MODE_CEILING
377
389
) ;
378
390
379
- if ( finalDigit < 10 ) {
380
- return {
381
- isNegative : x . isNegative ,
382
- significand : BigInt ( `${ cutoff } ${ finalDigit } ` ) ,
383
- exponent : exp ,
384
- } ;
385
- }
386
-
387
- let rounded = propagateCarryFromRight ( cutoff ) ;
388
-
389
391
return {
390
392
isNegative : x . isNegative ,
391
- significand : BigInt ( `${ rounded } 0 ` ) ,
393
+ significand : BigInt ( `${ cutoff } ${ finalDigit } ` ) ,
392
394
exponent : exp ,
393
395
} ;
394
396
}
395
397
396
- function roundTrunc ( x : SignedSignificandExponent ) : SignedSignificandExponent {
398
+ function roundFloor ( x : SignedSignificandExponent ) : SignedSignificandExponent {
397
399
let sig = x . significand . toString ( ) ;
398
400
let lastDigit = parseInt ( sig . charAt ( MAX_SIGNIFICANT_DIGITS ) ) as Digit ;
399
401
let cutoff = cutoffAfterSignificantDigits ( sig , MAX_SIGNIFICANT_DIGITS - 1 ) ;
@@ -408,19 +410,27 @@ function roundTrunc(x: SignedSignificandExponent): SignedSignificandExponent {
408
410
x . isNegative ,
409
411
penultimateDigit ,
410
412
lastDigit ,
411
- ROUNDING_MODE_TRUNCATE
413
+ ROUNDING_MODE_FLOOR
412
414
) ;
413
415
416
+ if ( finalDigit < 10 ) {
417
+ return {
418
+ isNegative : x . isNegative ,
419
+ significand : BigInt ( `${ cutoff } ${ finalDigit } ` ) ,
420
+ exponent : exp ,
421
+ } ;
422
+ }
423
+
424
+ let rounded = propagateCarryFromRight ( cutoff ) ;
425
+
414
426
return {
415
427
isNegative : x . isNegative ,
416
- significand : BigInt ( `${ cutoff } ${ finalDigit } ` ) ,
428
+ significand : BigInt ( `${ rounded } 0 ` ) ,
417
429
exponent : exp ,
418
430
} ;
419
431
}
420
432
421
- function roundHalfCeil (
422
- x : SignedSignificandExponent
423
- ) : SignedSignificandExponent {
433
+ function roundTrunc ( x : SignedSignificandExponent ) : SignedSignificandExponent {
424
434
let sig = x . significand . toString ( ) ;
425
435
let lastDigit = parseInt ( sig . charAt ( MAX_SIGNIFICANT_DIGITS ) ) as Digit ;
426
436
let cutoff = cutoffAfterSignificantDigits ( sig , MAX_SIGNIFICANT_DIGITS - 1 ) ;
@@ -435,7 +445,7 @@ function roundHalfCeil(
435
445
x . isNegative ,
436
446
penultimateDigit ,
437
447
lastDigit ,
438
- ROUNDING_MODE_HALF_CEILING
448
+ ROUNDING_MODE_TRUNCATE
439
449
) ;
440
450
441
451
return {
@@ -450,16 +460,14 @@ function adjustNonInteger(
450
460
options : FullySpecifiedConstructorOptions
451
461
) : SignedSignificandExponent {
452
462
switch ( options . roundingMode ) {
453
- case ROUNDING_MODE_HALF_EVEN :
454
- return roundHalfEven ( x ) ;
455
463
case ROUNDING_MODE_CEILING :
456
464
return roundCeiling ( x ) ;
457
465
case ROUNDING_MODE_FLOOR :
458
466
return roundFloor ( x ) ;
459
467
case ROUNDING_MODE_TRUNCATE :
460
468
return roundTrunc ( x ) ;
461
- case ROUNDING_MODE_HALF_CEILING :
462
- return roundHalfCeil ( x ) ;
469
+ case ROUNDING_MODE_HALF_EXPAND :
470
+ return roundHalfExpand ( x ) ;
463
471
default :
464
472
return roundHalfEven ( x ) ;
465
473
}
@@ -572,14 +580,13 @@ function handleInfinity(s: string): Decimal128Constructor {
572
580
} ;
573
581
}
574
582
575
- export const ROUNDING_MODE_CEILING : RoundingMode = "ceil " ;
576
- export const ROUNDING_MODE_FLOOR : RoundingMode = "floor " ;
577
- export const ROUNDING_MODE_TRUNCATE : RoundingMode = "trunc " ;
578
- export const ROUNDING_MODE_HALF_EVEN : RoundingMode = "halfEven " ;
579
- export const ROUNDING_MODE_HALF_CEILING : RoundingMode = "halfCeil " ;
583
+ export const ROUNDING_MODE_CEILING : RoundingMode = "roundTowardPositive " ;
584
+ export const ROUNDING_MODE_FLOOR : RoundingMode = "roundTowardNegative " ;
585
+ export const ROUNDING_MODE_TRUNCATE : RoundingMode = "roundTowardZero " ;
586
+ export const ROUNDING_MODE_HALF_EVEN : RoundingMode = "roundTiesToEven " ;
587
+ export const ROUNDING_MODE_HALF_EXPAND : RoundingMode = "roundTiesToAway " ;
580
588
581
- const ROUNDING_MODE_DEFAULT = ROUNDING_MODE_HALF_EVEN ;
582
- const CONSTRUCTOR_SHOULD_NORMALIZE = false ;
589
+ const ROUNDING_MODE_DEFAULT : RoundingMode = ROUNDING_MODE_HALF_EVEN ;
583
590
584
591
function roundIt (
585
592
isNegative : boolean ,
@@ -610,12 +617,8 @@ function roundIt(
610
617
return digitToRound ;
611
618
case ROUNDING_MODE_TRUNCATE :
612
619
return digitToRound ;
613
- case ROUNDING_MODE_HALF_CEILING :
620
+ case ROUNDING_MODE_HALF_EXPAND :
614
621
if ( decidingDigit >= 5 ) {
615
- if ( isNegative ) {
616
- return digitToRound ;
617
- }
618
-
619
622
return ( digitToRound + 1 ) as DigitOrTen ;
620
623
}
621
624
@@ -637,14 +640,19 @@ function roundIt(
637
640
}
638
641
}
639
642
640
- type RoundingMode = "ceil" | "floor" | "trunc" | "halfEven" | "halfCeil" ;
643
+ type RoundingMode =
644
+ | "roundTowardPositive"
645
+ | "roundTowardNegative"
646
+ | "roundTowardZero"
647
+ | "roundTiesToEven"
648
+ | "roundTiesToAway" ;
641
649
642
650
const ROUNDING_MODES : RoundingMode [ ] = [
643
- "ceil " ,
644
- "floor " ,
645
- "trunc " ,
646
- "halfEven " ,
647
- "halfCeil " ,
651
+ "roundTowardPositive " ,
652
+ "roundTowardNegative " ,
653
+ "roundTowardZero " ,
654
+ "roundTiesToEven " ,
655
+ "roundTiesToAway " ,
648
656
] ;
649
657
650
658
const digitStrRegExp =
@@ -659,14 +667,11 @@ interface ConstructorOptions {
659
667
660
668
interface FullySpecifiedConstructorOptions {
661
669
roundingMode : RoundingMode ;
662
- normalize : boolean ;
663
670
}
664
671
665
- const DEFAULT_CONSTRUCTOR_OPTIONS : FullySpecifiedConstructorOptions =
666
- Object . freeze ( {
667
- roundingMode : ROUNDING_MODE_DEFAULT ,
668
- normalize : CONSTRUCTOR_SHOULD_NORMALIZE ,
669
- } ) ;
672
+ const DEFAULT_CONSTRUCTOR_OPTIONS : FullySpecifiedConstructorOptions = {
673
+ roundingMode : ROUNDING_MODE_DEFAULT ,
674
+ } ;
670
675
671
676
type ToStringFormat = "decimal" | "exponential" ;
672
677
const TOSTRING_FORMATS : string [ ] = [ "decimal" , "exponential" ] ;
@@ -1349,6 +1354,10 @@ export class Decimal128 {
1349
1354
return this . clone ( ) ;
1350
1355
}
1351
1356
1357
+ if ( ! ROUNDING_MODES . includes ( mode ) ) {
1358
+ throw new RangeError ( `Invalid rounding mode "${ mode } "` ) ;
1359
+ }
1360
+
1352
1361
if ( numDecimalDigits < 0 ) {
1353
1362
numDecimalDigits = 0 ;
1354
1363
}
0 commit comments