DEV Community

Alex Chen
Alex Chen

Posted on

JavaScript Number Tricks Every Developer Should Know

JavaScript Number Tricks Every Developer Should Know

Numbers in JS are weird. Here's how to handle them correctly.

The Basics (That Everyone Gets Wrong)

// JS has only ONE number type: IEEE 754 double-precision float
typeof 42;        // "number"
typeof 3.14;      // "number"
typeof NaN;       // "number" (!)
typeof Infinity;  // "number" (!)

// Integer safety limit
Number.MAX_SAFE_INTEGER        // 9007199254740991 (~16 digits)
Number.MIN_SAFE_INTEGER        // -9007199254740991
Number.isSafeInteger(9007199254740992) // false — beyond safe range!

// Common gotchas:
0.1 + 0.2 === 0.3             // false! (0.30000000000000004)
0.1 + 0.2                     // 0.30000000000000004
Enter fullscreen mode Exit fullscreen mode

Formatting Numbers

const price = 1234.5678;
const users = 9876543;
const rating = 4.8523;

// Currency
price.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
// "$1,234.57"

price.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' });
// "1.234,57 €"

// Compact large numbers
users.toLocaleString('en-US', { notation: 'compact' });
// "988K"

users.toLocaleString('en-US', { notation: 'compact', compactDisplay: 'long' });
// "988 thousand"

// Percentage
(rating / 5).toLocaleString('en-US', { style: 'percent', minimumFractionDigits: 1 });
// "97.0%"

// Fixed decimal places
price.toFixed(2);              // "1234.57"
price.toFixed(0);              // "1235"

// With commas (locale-aware)
users.toLocaleString('en-US');   // "987,654"
users.toLocaleString('de-DE');   // "987.654"
Enter fullscreen mode Exit fullscreen mode

Math Operations You Actually Need

// Random integer in range [min, max]
function randomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}
randomInt(1, 6);    // Dice roll: 1-6
randomInt(0, 100);  // Percentage: 0-100

// Round to specific precision
function roundTo(num, decimals) {
  const factor = Math.pow(10, decimals);
  return Math.round(num * factor) / factor;
}
roundTo(3.14159, 2);   // 3.14
roundTo(99.956, 1);     // 99.96

// Clamp value between min and max
function clamp(value, min, max) {
  return Math.min(Math.max(value, min), max);
}
clamp(-5, 0, 100);     // 0
clamp(150, 0, 100);    // 100
clamp(50, 0, 100);     // 50

// Percentage calculation
function percentage(part, total) {
  return (part / total) * 100;
}
percentage(30, 200);   // 15
percentage(7, 28);     // 25

// Linear interpolation (lerp)
function lerp(start, end, t) {
  return start + (end - start) * t;
}
lerp(0, 100, 0.5);    // 50
lerp(10, 20, 0.75);   // 17.5

// Check if number is between two values (inclusive)
function isBetween(n, a, b) {
  return n >= Math.min(a, b) && n <= Math.max(a, b);
}
isBetween(5, 1, 10);   // true
isBetween(15, 1, 10);  // false
Enter fullscreen mode Exit fullscreen mode

Handling Money (The Right Way)

// ❌ NEVER use floating point for money!
const total = 0.1 + 0.2 + 0.1 + 0.1 + 0.1;
total === 0.5;          // false! (0.5000000000000001)

// ✅ Option 1: Work in cents (integers)
const priceCents = 1999; // $19.99
const taxCents = Math.round(priceCents * 0.08); // 160
const totalCents = priceCents + taxCents;         // 2159
const display = (totalCents / 100).toFixed(2);      // "21.59"

// ✅ Option 2: Use a library (dinero.js, currency.js)
import Dinero from 'dinero.js';

const price = Dinero({ amount: 1999, currency: 'USD' });
const tax = price.percentage(8);
const total = price.add(tax);
total.toFormat();           // "$21.59"
total.getAmount();          // 2159 (integer cents!)
Enter fullscreen mode Exit fullscreen mode

Number Validation

// Is it actually a number?
Number.isNaN(NaN);            // true
Number.isNaN('hello');        // false (unlike global isNaN!)
isNaN('hello');               // true (coerces to number first — confusing!)

Number.isFinite(42);          // true
Number.isFinite(Infinity);    // false
Number.isFinite(NaN);         // false

// Parse safely
parseInt('42px', 10);         // 42 (stops at non-digit)
parseFloat('3.14rem');        // 3.14
parseInt('hello', 10);        // NaN
Number('123');                // 123
Number('123abc');             // NaN

// Safe parsing utility
function parseNumber(val, fallback = 0) {
  const num = Number(val);
  return Number.isNaN(num) ? fallback : num;
}

parseNumber('42');            // 42
parseNumber('invalid');        // 0 (fallback)
parseNumber('', -1);           // -1 (custom fallback)
Enter fullscreen mode Exit fullscreen mode

BigInt (For Really Big Numbers)

// Regular numbers can't handle this:
Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2; // true!

// BigInt to the rescue:
const big = 9007199254740993n; // Note the 'n' suffix
big + 1n === big + 2n;        // false (correct!)

// Practical use: Database IDs, timestamps, crypto
const userId = 38429175839284759283n;
const timestamp = Date.now() * 1000000n + process.hrtime.bigint();

// Can't mix with regular numbers:
big + 1;                      // TypeError!
big + 1n;                     // OK

// Convert back and forth
BigInt(Number.MAX_SAFE_INTEGER); // 9007199254740991n
Number(9007199254740993n);      // 9007199254740993 (if within safe range)
Enter fullscreen mode Exit fullscreen mode

Unit Conversions

// Bytes to human-readable
function formatBytes(bytes, decimals = 2) {
  if (bytes === 0) return '0 Bytes';
  const k = 1024;
  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + ' ' + sizes[i];
}

formatBytes(0);                // "0 Bytes"
formatBytes(1024);             // "1 KB"
formatBytes(1048576);          // "1 MB"
formatBytes(1073741824);       // "1 GB"
formatBytes(15600000);         // "14.88 MB"

// Milliseconds to readable duration
function formatDuration(ms) {
  const seconds = Math.floor(ms / 1000);
  const minutes = Math.floor(seconds / 60);
  const hours = Math.floor(minutes / 60);
  const days = Math.floor(hours / 24);

  if (days > 0) return `${days}d ${hours % 24}h ${minutes % 60}m`;
  if (hours > 0) return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
  if (minutes > 0) return `${minutes}m ${seconds % 60}s`;
  return `${seconds}s`;
}

formatDuration(1000);           // "1s"
formatDuration(65000);         // "1m 5s"
formatDuration(3661000);       // "1h 1m 1s"
formatDuration(90000000);      // "1d 1h 0m"
Enter fullscreen mode Exit fullscreen mode

Quick Reference

Task Code Result
Format currency (1234.56).toLocaleString('en-US',{style:'currency'}) "$1,234.57"
Round to N places Math.round(x * 100) / 100 2 decimals
Random int Math.floor(Math.random() * (max-min+1)) + min Range
Clamp Math.min(Math.max(v, min), max) In range
Safe parse Number(x) or parseInt Number or NaN
Is integer? Number.isInteger(42) boolean
Is safe int? Number.isSafeInteger(x) boolean
To fixed x.toFixed(2) String
With commas x.toLocaleString() "1,234,567"
Percentage `((part/total)*100).toFixed(1) + '%' "25.0%"

What's your favorite number trick? Share it below!

Follow @armorbreak for more JavaScript content.

Top comments (0)