Free Number Formatter
Format numbers with commas, abbreviations, currency symbols, and custom decimal places.
How It Works
- Enter your number: Type or paste any numeric value, integers, decimals, large numbers, or scientific notation.
- Choose format options: Select your locale (US, EU, etc.), decimal places, grouping separator, and currency symbol if needed.
- Copy the formatted result: The number displays in your chosen format instantly. Copy it for use in reports, documents, or data exports.
Why Use Number Formatter?
Numbers mean different things in different locales. The US writes one thousand as 1,000.00 while many European countries write it as 1.000,00. Copying raw numbers between systems causes parse errors, misreads, and financial mistakes. The Number Formatter ensures your numbers display correctly for any audience, whether you're preparing financial reports, localizing content, or cleaning up data for presentation.
Features
- Locale-aware formatting: Supports US, EU, and international number formats with correct decimal and grouping separators.
- Decimal precision control: Set exactly how many decimal places to show.
- Thousands grouping: Add or remove thousands separators with a single click.
- Currency formatting: Prepend a currency symbol and format as a monetary value.
- Scientific notation: Convert to or from scientific notation for very large or small numbers.
Frequently Asked Questions
What is the difference between US and European number format?
In the US, the decimal separator is a period (.) and the thousands separator is a comma (,), e.g., 1,234.56. In most of Europe, it is reversed: 1.234,56. This tool converts between both formats correctly.
Can I format numbers for currencies?
Yes. Enable currency mode and select a symbol ($ € £ ¥ etc.) to prepend it to the formatted number. For accounting formats with negative number conventions, enable accounting mode.
Does it handle very large or very small numbers?
Yes. The formatter handles numbers with many digits and can display them in standard, grouped, or scientific notation. Floating-point precision is applied to the configured decimal places.
Where number formatting standards come from
The number formats you see in software today are defined by a small stack of standards that took thirty years to settle. IEEE 754 (1985), revised in 2008 and 2019, fixed the bit layout of binary floating-point numbers: 64 bits split into 1 sign, 11 exponent, 52 mantissa, which is what every JavaScript number is under the hood. ISO 4217 (1978, current edition 2015) defined the three-letter currency codes, USD, EUR, JPY, INR, BRL, and how many minor units each has (2 for USD, 0 for JPY, 3 for KWD, 4 for CLF). The Unicode CLDR (Common Locale Data Repository), first released in 2003, is the open dataset that records group separators, decimal separators, currency symbols, and plural rules for every locale; current release is CLDR 46 (October 2024). ECMA-402 (2012), the ECMAScript Internationalization API, gave JavaScript a native binding to that data via Intl.NumberFormat, which is backed by ICU (International Components for Unicode) in V8, JavaScriptCore, and SpiderMonkey. Together those four specs are what makes (1234567).toLocaleString('de-DE') return 1.234.567 instead of 1,234,567.
The six locale patterns you will meet
Most number formats in the wild fall into six patterns. Memorising these six covers ~95% of the user base of any global product.
- en-US, en-GB, ja-JP, zh-CN, ko-KR: comma group, period decimal:
1,234,567.89. - de-DE, es-ES, it-IT, nl-NL, pt-BR: period group, comma decimal:
1.234.567,89. Be careful pasting these into a US spreadsheet. - fr-FR, ru-RU, sv-SE, pl-PL: narrow no-break space group (Unicode U+202F), comma decimal:
1 234 567,89. The separator is not a regular space, copy-pasting through systems that normalise whitespace will corrupt it. - de-CH: right single quote group (U+2019), period decimal:
1’234’567.89. Switzerland is unique here. - en-IN, hi-IN: comma group, period decimal, but grouping is 2-2-3 instead of 3-3-3:
12,34,567.89. This reflects the lakh/crore system: 1 lakh = 10⁵, 1 crore = 10⁷. - ar-EG, ar-SA: Arabic-Indic digits (٠١٢٣٤٥٦٧٨٩), Arabic decimal U+066B, Arabic thousands separator U+066C:
١٬٢٣٤٬٥٦٧٫٨٩. Most Arabic-speaking developer environments use Latin digits internally and only switch for display.
Rounding modes, what they actually do
ECMA-402 (2023) added nine rounding modes to Intl.NumberFormat. The choice changes financial totals, scientific reports, and tax calculations. Three matter most in practice.
halfExpand(default). 2.5 rounds to 3, −2.5 rounds to −3. This is the rounding everyone learned in school and the JavaScript default.halfEven(banker's rounding). 2.5 rounds to 2, 3.5 rounds to 4, ties always go to the even digit. Required by IEEE 754 for floating-point arithmetic. Used in US tax tables, scientific computing, and major accounting systems to remove a small systematic bias thathalfExpandintroduces over millions of rounds.trunc. Drops everything past the cutoff with no rounding. 2.9 → 2, −2.9 → −2. Used when you literally want to discard precision, never for money.- The other six (
ceil,floor,expand,halfCeil,halfFloor,halfTrunc) handle specialised cases like always rounding up for shipping costs or always rounding down for tax discounts. Pick deliberately, don't accept the default if money or compliance is involved.
Where this tool earns its keep
- Financial reports. Format revenue, expenses, ratios for slide decks. Toggle between US and EU formats to match the audience's country.
- Locale-checking your store. Type a price in the format you want and verify it matches what your e-commerce site renders for a customer in Germany or India.
- CSV preparation. Convert German
1.234,56rows to US1234.56before importing into a sheet that expects period-decimal, or vice versa. - Indian rupee formatting. Turn 12,500,000 into 1,25,00,000 (1.25 crore) for South Asian audiences. Most US-built tools don't do this.
- Dashboard compact display. Turn 1,234,567 into
1.23Mfor widgets where horizontal space is tight. Compact notation is also locale-aware: German shows1,23 Mio.. - Currency symbol prepending. Add $, €, £, ¥, ₹ in the correct position for each locale, US dollar sits in front, German euro sits after.
- Excel scientific-notation escape. Pasted big IDs like Twitter snowflakes get converted to
1.23E+18and lose precision. Format them with grouping plus a leading apostrophe before pasting so Excel treats them as text.
Mistakes that bite even experienced developers
- Floating-point arithmetic on money.
0.1 + 0.2 === 0.30000000000000004in every IEEE 754 language, not just JavaScript. Store currency as integer minor units (cents) or use a decimal library likedecimal.js. Formatting hides the error, it doesn't fix it. - Naive parsing of locale strings.
parseFloat("1,234.56")returns1, not1234.56.parseFloat("1.234,56")returns1.234. To parse a locale-formatted number, strip group separators then replace the decimal mark, ideally driven byIntl.NumberFormat(locale).formatToParts(). - Big-int precision loss. Integers above
2⁵³ − 1 = 9 007 199 254 740 991silently lose precision when stored asnumber. Twitter IDs, Stripe IDs, blockchain transaction hashes all exceed this. Receive them as strings or useBigInt;Intl.NumberFormataccepts BigInt natively. - Stripe-style minor units. Stripe sends
amount: 499for $4.99. Divide by 100 (or by the ISO 4217 minor-unit count for the currency) before formatting. JPY, KRW, VND, ISK, HUF use 0 minor units, no division needed. - Percent input is a fraction.
new Intl.NumberFormat('en', {style: 'percent'}).format(0.5)returns50%, not0.5%. Multiply your stored value by 0.01 before formatting if you stored it as a percentage. - Constructing NumberFormat in a hot loop. Each constructor call loads ICU locale data. Reuse a single instance across calls: 1M formats with a cached instance takes ~60 ms in V8, ~3 s if you construct fresh every time.
- JPY with two decimal places.
¥1000.00looks wrong because JPY has 0 minor units. SetminimumFractionDigits: 0, maximumFractionDigits: 0for JPY, KRW, VND, ISK, HUF, CLP, ISK.
More frequently asked questions
Why does 0.1 + 0.2 not equal 0.3?
Because IEEE 754 binary floats cannot store the decimal fraction 0.1 exactly, in the same way that base-10 cannot store 1/3 exactly. The closest 64-bit double to 0.1 is roughly 0.1000000000000000055511151231257827021181583404541015625. Adding two such approximations produces a result that rounds to 0.30000000000000004 instead of 0.3. Every IEEE 754 language has this behaviour: Java, Python, C++, Swift, all of them. For exact decimal arithmetic, use integer cents or a library like decimal.js / Python's Decimal / Java's BigDecimal.
What is the difference between Intl.NumberFormat and toLocaleString?
Same engine, different ergonomics. (1234.5).toLocaleString('de-DE', {style: 'currency', currency: 'EUR'}) and new Intl.NumberFormat('de-DE', {style: 'currency', currency: 'EUR'}).format(1234.5) produce identical output. The difference: Intl.NumberFormat is reusable, so if you format many numbers with the same options, instantiate once and cache. toLocaleString reads the constructor options every call and is dramatically slower in tight loops.
How does the Indian numbering system work?
Indian English and Hindi group digits in a 2-2-3 pattern instead of 3-3-3: rightmost three digits, then groups of two. 100,000 is written 1,00,000 and called one lakh (10⁵). 10,000,000 is written 1,00,00,000 and called one crore (10⁷). Intl.NumberFormat('en-IN').format(12345678) returns 1,23,45,678. The system extends to arab (10⁹) and kharab (10¹¹) though those are rare in modern usage.
How big a number can this tool handle?
Up to Number.MAX_SAFE_INTEGER = 2⁵³ − 1 = 9,007,199,254,740,991, any integer survives a round trip exactly. Beyond that, precision starts to leak. JSON.parse("9007199254740993") returns 9007199254740992, the closest representable double. For larger values, paste them as BigInt literals (with a trailing n) or treat them as strings. The formatter accepts both.
Is my number sent anywhere?
No. Intl.NumberFormat and the locale data ship with your browser; the entire pipeline runs locally. Open the Network tab in DevTools and format a number, you will see zero outbound requests. Safe for salaries, revenue, account balances, or any data you would not paste into a hosted service.