Skip to main content
Version: 1.3.3

Decimal

Arbitrary precision decimal math. Add, subtract, multiply, divide numbers, shift digits left and right, with control over rounding and precision or scale of the result.

new

Constructs a new decimal value from a number or string.

Syntax

new Decimal(num)

Parameters

  • num: number | string | Decimal
    • The number to parse into a Decimal

Example

import { Decimal } from '@phensley/cldr';
const s = Number.MAX_SAFE_INTEGER;
const n = new Decimal(`${s}${s}.${s}`);
log(n);
90071992547409919007199254740991.9007199254740991
import { Decimal } from '@phensley/cldr';
for (const num of ['-10', 0, '123', Infinity, -Infinity, NaN]) {
const d = new Decimal(num);
log(d.toString());
}
-10
0
123
Infinity
-Infinity
NaN

abs

Return the absolute value of the number.

Syntax

abs(): Decimal

Example

import { Decimal } from '@phensley/cldr';
const n = new Decimal('-123.456');
log(n.abs().toString());
123.456

add

Adds the argument to this number, returning the sum. The scale of the result will be max(this.scale(), n.scale()).

Syntax

add(n): Decimal

Parameters

  • n: number | string | Decimal
    • The number to add to this one.

Example

import { Decimal } from '@phensley/cldr';
const a = new Decimal('0.003');
const b = new Decimal('0.0005');
const c = a.add(b).add(b);
log(c.toString());
0.0040

compare

Compare the decimal u to v, returning a number indicating whether one is larger or they are equal.

The abs

Syntax

compare(v [, abs]): number

Parameters

  • v: number | string | Decimal
    • Number to compare
  • abs: boolean
    • If true compare the absolute values, defaults to false.

Return value

  • Returns a number with one of the following values:
  -1  if u < v
   0  if u = v
   1  if u > v

Example

import { Decimal } from '@phensley/cldr';
const w = (s: string) => ' '.repeat(10 - s.length) + s;

const cmp = (a: string, b: string) =>
log(`${w(a)} cmp ${w(b)} = ${new Decimal(a).compare(b)}`);

cmp('1234', '1234');
cmp('1e10', '1e11');
cmp('1.23e5', '12e4');
cmp('12e4', '1.23e5');
cmp('-12e4', '1.23e5');
cmp('-1.23e5', '12e4');
cmp('1.2345e-10', '12e4');
      1234   cmp       1234 = 0
      1e10   cmp       1e11 = -1
    1.23e5   cmp       12e4 = 1
      12e4   cmp     1.23e5 = -1
     -12e4   cmp     1.23e5 = -1
   -1.23e5   cmp       12e4 = -1
1.2345e-10   cmp       12e4 = -1

decrement

Subtracts 1 from the number.

Syntax

decrement(): Decimal

Example

import { Decimal } from '@phensley/cldr';
const n = new Decimal('1.57');
log(n.decrement().toString());
0.57

divide

Divides a number by its argument, using the given context.

Syntax

divide(number, context?): Decimal

Parameters

  • number: number | string | Decimal
    • Divisor
  • context?: MathContext
    • Context to use for scale, precision, rounding

Example

import { Decimal } from '@phensley/cldr';
const rounding: RoundingModeType[] = ['half-even', 'floor'];
const n = new Decimal('1000');

for (const round of rounding) {
log(round);

for (const scale of [5, 10, 15]) {
const r = n.divide(6, { scale, round });
log(` ${r.toString()}`);
}
}
half-even
  166.66667
  166.6666666667
  166.666666666666667
floor
  166.66666
  166.6666666666
  166.666666666666666

divmod

Divides a number by its argument, returning the quotient and remainder as a pair.

Syntax

divmod(number): [Decimal, Decimal]

Parameters

  • number: number | string | Decimal
    • Divisor

Example

import { Decimal } from '@phensley/cldr';
const n = new Decimal('100');
for (const d of [3, 12, 15.7, 37.82, 90.122]) {
const [q, r] = n.divmod(d);
log(`(${n.toString()} / ${d}) is ${q.toString()} r ${r.toString()}`);
}
(100 / 3) is 33 r 1
(100 / 12) is 8 r 4
(100 / 15.7) is 6 r 5.8
(100 / 37.82) is 2 r 24.36
(100 / 90.122) is 1 r 9.878

increment

Adds 1 to a number.

Syntax

increment(): Decimal

Example

import { Decimal } from '@phensley/cldr';
const n = new Decimal('-0.57');
log(n.increment().toString());
0.43

integerDigits

Count of the number of integer digits. Always returns a number >= 1.

Syntax

integerDigits(): number

Example

import { Decimal } from '@phensley/cldr';
for (const s of ['.123', '12345.9999999', '1e20']) {
const n = new Decimal(s);
const d = n.integerDigits();
log(`${n.toString()} has ${d} integer digit${d === 1 ? '' : 's'}`);
}
0.123 has 1 integer digit
12345.9999999 has 5 integer digits
100000000000000000000 has 21 integer digits

isInteger

Indicates if this number is an integer or has a fractional part.

Syntax

isInteger(): boolean

Example

import { Decimal } from '@phensley/cldr';
for (const s of ['0', '5', '1e10', '.123', '12345.9999999', '5.999999999999999999999']) {
const n = new Decimal(s);
log(`${n.toString()} ${n.isInteger() ? 'yes' : 'no'}`);
}
0 yes
5 yes
10000000000 yes
0.123 no
12345.9999999 no
5.999999999999999999999 no

isNegative

Indicates if this number is negative.

Syntax

isNegative(): boolean

Example

import { Decimal } from '@phensley/cldr';
for (const s of ['0', '123', '-15.7']) {
const neg = new Decimal(s).isNegative();
log(`${s} ${neg ? 'is' : 'is not'} negative`);
}
0 is not negative
123 is not negative
-15.7 is negative

mod

Divides a number by an argument and returns the remainder.

Note This differs from the modulo operator in math in that it can return a negative number.

Syntax

mod(number): Decimal

Parameters

  • n: number
    • Number to divide by

Example

import { Decimal } from '@phensley/cldr';
const n = new Decimal(777);
for (const m of [2, 3, 4, 5, 6]) {
const a = n.mod(m);
const b = n.negate().mod(m);
log(`${n.toString()} % ${m} = ${a.toString()} ` +
`-${n.toString()} % ${m} = ${b.toString()}`);
}
777 % 2 = 1   -777 % 2 = -1
777 % 3 = 0   -777 % 3 = -0
777 % 4 = 1   -777 % 4 = -1
777 % 5 = 2   -777 % 5 = -2
777 % 6 = 3   -777 % 6 = -3

movePoint

Move the decimal point left or right n places. Does not change precision, it only affects the exponent.

Moves to the left if n is negative, and to the right if positive.

Syntax

movePoint(n): Decimal

Parameters

  • n: number
    • Number of places to move the decimal point left (if negative) or right (if positive)

Example

import { Decimal } from '@phensley/cldr';
const n = new Decimal('12345.6789');
for (const p of [-5, -3, -1, 1, 3, 5]) {
log(n.movePoint(p).toString());
}
0.123456789
12.3456789
1234.56789
123456.789
12345678.9
1234567890

multiply

Multiply a number by its argument, using the given math context.

Syntax

multiply(number, context?): Decimal

Parameters

  • number: number | string | Decimal
    • Multiplier
  • context?: MathContext
    • Context to use for scale, precision, rounding

Example

import { Decimal, DecimalConstants } from '@phensley/cldr';
const { E, PI } = DecimalConstants;
const n = new Decimal('7');
for (const m of ['12', '1e10', '0.0000004737', '0.9999999', PI, E]) {
const r = n.multiply(m, { scale: 30 });
log(r.stripTrailingZeros());
}
84
70000000000
0.0000033159
6.9999993
21.991148575128552669238503682957
19.027972799213316647522012299469

negate

Inverts the sign of the number.

Syntax

negate(): Decimal

Example

import { Decimal } from '@phensley/cldr';
for (const n of ['-5', '3.1415']) {
log(new Decimal(n).negate());
}
5
-3.1415

precision

Returns the precision in the number. Precision indicates the number of digits used to express the value.

For example the number 1e10 has 1 digit of precision, while 123e10 has 3.

Syntax

precision(): number

Example

import { Decimal } from '@phensley/cldr';
for (const n of ['1', '1e10', '1.2345']) {
log(new Decimal(n).precision());
}
1
1
5

scale

Returns the scale of the number. Scale that is zero or positive indicates the number of digits to the right of the decimal point. A negative scale indicates the negated power of 10 the unscaled value is multiplied by.

For example the number 1.234 has a scale of 3 while 1e10 has a scale of -10.

Syntax

scale(): number

Example

import { Decimal } from '@phensley/cldr';
for (const n of ['1', '1e-10', '1e10', '1.2345', '1.234e10']) {
log(`${n} scale ${new Decimal(n).scale()}`);
}
1 scale 0
1e-10 scale 10
1e10 scale -10
1.2345 scale 4
1.234e10 scale -7

scientific

Return the coefficient and adjusted exponent of the number, suitable for displaying scientific notation.

Syntax

scientific(minIntDigits: number = 1): [Decimal, number]

Example

import { Decimal } from '@phensley/cldr';
const n = new Decimal('157.39E10');
const [coeff, exp] = n.scientific();
log(`${coeff.toString()} x 10^${exp}`);
1.5739 x 10^12

setScale

Sets the scale of this number.

Syntax

setScale(number): Decimal

Example

import { Decimal } from '@phensley/cldr';
const n = new Decimal('12345.678');
for (let scale = -5; scale <= 5; scale++) {
const r = n.setScale(scale);
log(`scale ${scale} = ${r}`);
}
scale -5 = 0
scale -4 = 10000
scale -3 = 12000
scale -2 = 12300
scale -1 = 12350
scale 0 = 12346
scale 1 = 12345.7
scale 2 = 12345.68
scale 3 = 12345.678
scale 4 = 12345.6780
scale 5 = 12345.67800

shiftleft

Shift digits n places to the left, increasing precision.

Syntax

shiftleft(shift): Decimal

Example

import { Decimal } from '@phensley/cldr';
for (const n of ['1', '0.123456789']) {
log(n.toString());
for (let shift = 1; shift <= 10; shift++) {
const r = new Decimal(n).shiftleft(shift);
log(` ${shift} -> ${r}`);
}
}
1
  1 -> 10
  2 -> 100
  3 -> 1000
  4 -> 10000
  5 -> 100000
  6 -> 1000000
  7 -> 10000000
  8 -> 100000000
  9 -> 1000000000
  10 -> 10000000000
0.123456789
  1 -> 1.234567890
  2 -> 12.345678900
  3 -> 123.456789000
  4 -> 1234.567890000
  5 -> 12345.678900000
  6 -> 123456.789000000
  7 -> 1234567.890000000
  8 -> 12345678.900000000
  9 -> 123456789.000000000
  10 -> 1234567890.000000000

shiftright

Shifts digits n places to the right and rounds, reducing precision.

Note that when the shift is equal to or greater than the precision it can shift the number to zero. The exponent is also preserved even when the number is shifted to zero.

Syntax

shiftright(shift, round?): Decimal

Parameters

  • shift: number
    • Number of decimal places to shift
  • round?: RoundingModeType
    • Rounding mode to use

Example

import { Decimal } from '@phensley/cldr';
for (const n of ['12345.67890', '55555.55555']) {
log(n.toString());
for (let shift = 1; shift <= 10; shift++) {
const r = new Decimal(n).shiftright(shift);
log(` ${shift} -> ${r}`);
}
}
12345.67890
  1 -> 12345.6789
  2 -> 12345.679
  3 -> 12345.68
  4 -> 12345.7
  5 -> 12346
  6 -> 12350
  7 -> 12300
  8 -> 12000
  9 -> 10000
  10 -> 0
55555.55555
  1 -> 55555.5556
  2 -> 55555.556
  3 -> 55555.56
  4 -> 55555.6
  5 -> 55556
  6 -> 55560
  7 -> 55600
  8 -> 56000
  9 -> 60000
  10 -> 0

signum

Returns 1 if the sign of the number is positive, -1 if negative, and 0 if equal to 0.

Syntax

signum(): number

Example

import { Decimal } from '@phensley/cldr';
for (const n of ['0', '-1.2', '345', '10e-10', '-10e10']) {
log(`${n} signum is ${new Decimal(n).signum()}`);
}
0 signum is 0
-1.2 signum is -1
345 signum is 1
10e-10 signum is 1
-10e10 signum is -1

stripTrailingZeros

Remove any trailing zeros from a number.

Syntax

stripTrailingZeros(): Decimal

Example

import { Decimal } from '@phensley/cldr';
for (const n of ['1.0', '0.9999900000', '1.57000000', '1e10']) {
log(new Decimal(n).stripTrailingZeros().toString());
}
1
0.99999
1.57
10000000000

subtract

Subtract the argument from this number.

Syntax

subtract(number): Decimal

Parameters

  • number: number | string | Decimal
    • Number to subtract

Example

import { Decimal, DecimalConstants } from '@phensley/cldr';
const { E } = DecimalConstants;
const n = new Decimal('1');
for (const m of ['.999999', '37.79', E]) {
let r = n.subtract(m);
if (r.scale() > 20) {
r = r.setScale(20);
}
log(r.toString());
}
0.000001
-36.79
-1.71828182845904523536

toParts

Render a number into an array of Part.

Syntax

toParts(): Part[]

Example

import { Decimal } from '@phensley/cldr';
for (const n of ['3', '1e10', '3.14159']) {
log(new Decimal(n).toParts());
}
[ { type: 'integer', value: '3' } ]
[ { type: 'integer', value: '10000000000' } ]
[
  { type: 'integer', value: '3' },
  { type: 'decimal', value: '.' },
  { type: 'fraction', value: '14159' }
]

toString

Syntax

toString(): string

Example

import { Decimal } from '@phensley/cldr';
const s = Number.MAX_SAFE_INTEGER;
const n = new Decimal(`${s}${s}.${s}`);
log(n.toString());
90071992547409919007199254740991.9007199254740991

toScientificParts

Format the number in scientific notation as an array of parts.

Syntax

toScientificParts(minIntegers: number = 1): Part[]

Example

import { Decimal } from '@phensley/cldr';
const n = new Decimal('157.39E10');
log(n.toScientificParts());
[
  { type: 'integer', value: '1' },
  { type: 'decimal', value: '.' },
  { type: 'fraction', value: '5739' },
  { type: 'exp', value: 'E' },
  { type: 'plus', value: '+' },
  { type: 'integer', value: '12' }
]

toScientificString

Format the number in scientific notation as a string.

Syntax

toScientificString(minIntegers: number = 1): string

Example

import { Decimal } from '@phensley/cldr';
const n = new Decimal('157.39E10');
log(n.toScientificString());
1.5739E+12

trailingZeros

Returns the number of trailing decimal zeros.

Syntax

trailingZeros(): number

Example

import { Decimal } from '@phensley/cldr';
for (const n of ['1', '1e10', '0.12300000']) {
log(new Decimal(n).trailingZeros());
}
0
0
5

References