Number.prototype.toPrecision()

The one people reach for when they wanted toFixed. It counts digits from the left of the number, so the same argument produces wildly different output depending on magnitude.

Number methodES3 (1999)Live demo
Common call
n.toPrecision(3)
Returns
a string with that many significant digits
Replaces
manual scientific rounding
Watch out
large numbers come back in exponential form
number.toPrecision([digits])
→ string

Demo

Live evaluation
Try:
Inputs
nnumbera number
pnumbersignificant digits
Output
(123.456).toPrecision(4)
'123.5'

Significant digits are counted from the first non-zero digit, so 123.456 to four gives '123.5' — three before the point and one after. The second case is the surprise: asking for two significant digits from 123456 cannot be written in fixed notation without implying six digits of precision, so the method switches to '1.2e+5'. Formatting code that expected plain digits gets exponential notation instead. The small-fraction case shows the leading zeros are not counted as significant, and the fourth shows zeros are padded on to reach the requested count.

Parameters

NameTypeRequiredDescription
digitsnumberno (as many as needed)Significant digits, 1 to 100. Omitted entirely, the method behaves exactly like toString. Outside the range it throws RangeError.

Return value

string — A string with the given number of SIGNIFICANT digits — counted from the first non-zero digit, not from the decimal point. Falls back to exponential notation when fixed notation would need more digits than requested.

Common patterns

Scientific or measurement output
Where significant figures are the convention.
const shown = measurement.toPrecision(3);
Decimal places instead
Almost always what UI code actually wants.
const shown = price.toFixed(2);
Guard against exponential output
Check before showing it to a user.
const s = n.toPrecision(3);
const safe = s.includes("e") ? n.toFixed(2) : s;

Examples

1. Four significant
(123.456).toPrecision(4)
Returns
'123.5'
2. Goes exponential
(123456).toPrecision(2)
Returns
'1.2e+5'
3. Small fraction
(0.000123).toPrecision(2)
Returns
'0.00012'
4. Zeros padded
(1).toPrecision(5)
Returns
'1.0000'
5. toFixed differs
(123456).toFixed(2)
Returns
'123456.00'
6. It is a string
typeof (1).toPrecision(2)
Returns
'string'

Pitfalls

1. It counts significant digits, not decimals
The most common mix-up with toFixed. toPrecision(2) on 123456 keeps two digits of the whole number; toFixed(2) keeps two digits after the point. They agree only by coincidence, and only for numbers of one particular magnitude.
Not two decimals
(123456).toPrecision(2)
'1.2e+5'
toFixed for decimals
(123456).toFixed(2)
'123456.00'
2. It switches to exponential silently
When the requested precision is fewer digits than the integer part needs, fixed notation would be misleading, so the method uses exponential form. Output you expected to be plain digits arrives as 1.2e+5 in the middle of a sentence.
Unexpected form
(123456).toPrecision(2)
'1.2e+5'
Detect and fall back
const s = n.toPrecision(2);
s.includes("e") ? n.toFixed(0) : s
plain digits
3. It returns a string
Same as toFixed and toExponential. Arithmetic on the result concatenates, and a comparison against a number coerces in ways that are rarely what you want.
Concatenation
(1).toPrecision(2) + 1
'1.01'
Convert back
Number((1).toPrecision(2)) + 1
2
4. Omitting the argument changes the method entirely
With no argument it does not pick a sensible default precision — it behaves exactly like toString and returns the full representation. A variable that is sometimes undefined therefore produces inconsistent output.
Full precision
(123.456).toPrecision()
'123.456'
Always pass one
(123.456).toPrecision(4)
'123.5'

When to use

Use it
  • Scientific and engineering output, where significant figures are standard
  • Normalising numbers of wildly different magnitudes to the same information content
  • Deliberately producing exponential notation for very large or small values
Reach for something else
  • Money and UI numbers → toFixed, or Intl.NumberFormat
  • You need exponential always → toExponential
  • You need a number back → this returns a string
  • Locale-aware output → toLocaleString

Notes

Complexity
O(1)
Return
A new string; the number is unchanged
CPython impl
V8: Builtins-number-toprecision
Memory
Allocates the result string
Thread-safe
Single-threaded

FAQ

toFixed for anything with a fixed unit — money, percentages, measurements shown to a set number of decimals. toPrecision when the significant information content matters regardless of magnitude, which is mostly scientific work.

(0.001234).toFixed(2);       // '0.00'  — all detail lost
(0.001234).toPrecision(2);   // '0.0012' — two significant digits

History

ES3
toPrecision added with toFixed and toExponential.