How to Get the Decimal Part of a Number in TypeScript

You can get the decimal part of a number in TypeScript with the remainder operator: x % 1 returns everything after the decimal point as a number. For 24.75 that’s 0.75, and an integer gives 0:

const fraction = price % 1;   // 24.75 -> 0.75

My test machine runs TypeScript 7.0.2 and Node.js v22.22.2; I built each file with strict checks on and copied the real console output under it.

Get the decimal part with % 1 or Math.trunc()

The remainder of dividing by 1 is the fraction. Subtracting the whole part, x - Math.trunc(x), gives the same result, and Math.trunc() on its own hands you the integer part:

const price: number = 24.75;

const viaRemainder = price % 1;
const viaTrunc = price - Math.trunc(price);
const wholePart = Math.trunc(price);

console.log("price % 1           :", viaRemainder);
console.log("price - trunc(price):", viaTrunc);
console.log("whole part          :", wholePart);
console.log("is 42 an integer?   :", Number.isInteger(42), "->", 42 % 1);

Output:

price % 1           : 0.75
price - trunc(price): 0.75
whole part          : 24
is 42 an integer?   : true -> 0

I reach for % 1 when I only need the fraction, and the Math.trunc() pair when I also want whole dollars or units. Got the value as text? Convert it with string to number conversion in TypeScript.

For an integer check, Number.isInteger(x) reads better than x % 1 === 0, and it narrows nicely with type narrowing in TypeScript.

How do negative numbers change the decimal part?

Here the methods split. % keeps the sign of the left operand and Math.trunc() cuts toward zero, so both give a negative fraction. Math.floor() rounds toward negative infinity, so it gives a positive one:

const values: number[] = [3.75, -3.75, -0.5, -5];

for (const x of values) {
  console.log(
    String(x).padStart(5),
    "| % 1:", String(x % 1).padStart(5),
    "| x - trunc:", String(x - Math.trunc(x)).padStart(5),
    "| x - floor:", String(x - Math.floor(x)).padStart(4),
    "| abs(% 1):", Math.abs(x % 1),
  );
}
console.log("Object.is(-5 % 1, -0):", Object.is(-5 % 1, -0));

Output:

 3.75 | % 1:  0.75 | x - trunc:  0.75 | x - floor: 0.75 | abs(% 1): 0.75
-3.75 | % 1: -0.75 | x - trunc: -0.75 | x - floor: 0.25 | abs(% 1): 0.75
 -0.5 | % 1:  -0.5 | x - trunc:  -0.5 | x - floor:  0.5 | abs(% 1): 0.5
   -5 | % 1:     0 | x - trunc:     0 | x - floor:    0 | abs(% 1): 0
Object.is(-5 % 1, -0): true
Command Prompt output comparing x % 1, x - Math.trunc(x) and x - Math.floor(x) for positive and negative numbers in TypeScript
For -3.75, % 1 and trunc give -0.75, while floor gives 0.25. Math.abs() returns the plain digits.

Pick by meaning: Math.abs(x % 1) for the digits after the point, or x - Math.floor(x) when you need a value in [0, 1).

One oddity: -5 % 1 is actually -0, as Object.is shows. It equals 0 with ===, so it rarely matters.

Why is the decimal part of 3.14 not exactly 0.14?

TypeScript numbers are 64-bit binary floats, so most decimal fractions aren’t stored exactly. Removing the whole part exposes the error that console.log(3.14) hides:

const samples: number[] = [3.14, 1.37, 19.99, 1234.56];

for (const x of samples) {
  console.log(`${x} % 1 =`, x % 1);
}

function decimalPart(x: number, digits = 2): number {
  const frac = x % 1;
  const factor = 10 ** digits;
  return Math.round(frac * factor) / factor;
}

console.log("decimalPart(3.14)       :", decimalPart(3.14));
console.log("decimalPart(-3.14)      :", decimalPart(-3.14));
console.log("typeof (3.14 % 1).toFixed(2) :", typeof (3.14 % 1).toFixed(2));
console.log("(1.005).toFixed(2)      :", (1.005).toFixed(2));

Output:

3.14 % 1 = 0.14000000000000012
1.37 % 1 = 0.3700000000000001
19.99 % 1 = 0.9899999999999984
1234.56 % 1 = 0.5599999999999454
decimalPart(3.14)       : 0.14
decimalPart(-3.14)      : -0.14
typeof (3.14 % 1).toFixed(2) : string
(1.005).toFixed(2)      : 1.00
Command Prompt output of TypeScript showing floating-point noise from 3.14 % 1 and the fix with Math.round and toFixed
Raw remainders carry noise; rounding to a fixed number of digits cleans them up.

Round to the digits you care about. My decimalPart() helper returns a number; toFixed(2) returns a string, so wrap it in Number() for more math. More rounding options are in rounding to 2 decimal places in TypeScript.

Watch the last line: (1.005).toFixed(2) gives "1.00", because 1.005 is really stored as 1.00499999… Don’t treat toFixed as a money calculator.

Decimal part of a string: the TS2362 error

Form, CSV and query-string values are strings, and TypeScript won’t let you use % on them. You’ll see this:

const fromForm: string = "19.99";       // value from an input field

const cents = fromForm % 1;

Output:

decimal_string_error.ts(3,15): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
Command Prompt showing TypeScript error TS2362 when using the remainder operator on a string value
TS2362: the left side of an arithmetic operation has to be a number, bigint or enum.

Parse it with Number() or parseFloat() first. I compare those in converting a string to a double in TypeScript, and checking whether a string is a number catches bad input.

Get the decimal digits as a string with split(‘.’)

Sometimes you want the digits as text, like "05" for 8.05. Splitting String(x) on the dot does that, with sharp edges:

function decimalDigits(x: number): string {
  const [, digits = ""] = String(x).split(".");
  return digits;
}

console.log("24.75  ->", decimalDigits(24.75));
console.log("8.05   ->", decimalDigits(8.05));
console.log("12     ->", JSON.stringify(decimalDigits(12)));
console.log("1.5e-7 ->", decimalDigits(1.5e-7), " String():", String(1.5e-7));
console.log("2.5e21 ->", JSON.stringify(decimalDigits(2.5e21)), " String():", String(2.5e21));

const german = (1234.56).toLocaleString("de-DE");
console.log("de-DE text:", german, "->", german.split(".")[1]);

const safe = (x: number) => x.toFixed(2).split(".")[1];
console.log("toFixed(2) split:", safe(1.5e-7), safe(1234.56));

Output:

24.75  -> 75
8.05   -> 05
12     -> ""
1.5e-7 -> 5e-7  String(): 1.5e-7
2.5e21 -> "5e+21"  String(): 2.5e+21
de-DE text: 1.234,56 -> 234,56
toFixed(2) split: 00 56

Three results are wrong. Tiny and huge values switch to exponent notation, so 1.5e-7 yields "5e-7" and 2.5e21 yields "5e+21". And German toLocaleString() output uses a comma, so the split grabs the wrong piece.

If you need text, fix the digits first: x.toFixed(2).split(".")[1] never uses exponent notation for values under 1e21. For display formatting, see formatting numbers with 2 digits in TypeScript.

Get cents from a USD amount with integer math

Money is where decimal noise bites. Truncating the fraction times 100 loses a cent on common prices, so it’s safer to convert the whole amount to integer cents once:

const amounts: number[] = [19.99, 4.35, 1250.1, 0.07];

for (const usd of amounts) {
  const naiveCents = Math.trunc((usd % 1) * 100);
  const totalCents = Math.round(usd * 100);   // whole cents as an integer
  const dollars = Math.trunc(totalCents / 100);
  const cents = totalCents % 100;
  console.log(
    `${("$" + usd.toFixed(2)).padStart(9)}  naive: ${String(naiveCents).padStart(2)}`,
    ` dollars: ${String(dollars).padStart(4)}  cents: ${String(cents).padStart(2, "0")}`,
  );
}

Output:

   $19.99  naive: 98  dollars:   19  cents: 99
    $4.35  naive: 34  dollars:    4  cents: 35
 $1250.10  naive:  9  dollars: 1250  cents: 10
    $0.07  naive:  7  dollars:    0  cents: 07
Command Prompt output of TypeScript extracting dollars and cents from USD amounts with Math.round integer math
The naive version gives 98 cents for $19.99 and 34 for $4.35; rounding to whole cents first is right every time.

My rule: Math.round(usd * 100) as soon as a price arrives, do the math in integer cents, and format at the end. I do the same when totaling carts with the TypeScript array reduce method.

Ways to get the decimal part in TypeScript compared

ApproachResult for -3.75Use it when
x % 1-0.75You want the fraction with the same sign
x - Math.trunc(x)-0.75You also need the whole part
x - Math.floor(x)0.25You need a value in [0, 1)
Math.abs(x % 1)0.75You want the plain digits
Math.round(x * 100) % 100-75Cents from a money amount

Here are a few more number guides worth a look:

Frequently asked questions

How do I get the decimal part of a number in TypeScript?

Use x % 1. It returns 0.75 for 24.75 and 0 for an integer.

Why is the decimal part negative for negative numbers?

% keeps the sign of the left operand, so -3.75 % 1 is -0.75. Wrap it in Math.abs() if you don’t want the sign.

How do I remove floating-point noise like 0.14000000000000012?

Round to the digits you need: Math.round(frac * 100) / 100, or Number(frac.toFixed(2)).

How do I get the cents from a dollar amount?

Use Math.round(usd * 100) % 100. Don’t truncate the raw fraction times 100.

Is splitting the string on the dot safe?

Not on its own. String() uses exponent notation for tiny or huge values. Call toFixed() first.

Where is the remainder operator documented?

See Remainder (%) on MDN.