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 Floating Point Problem

0.1 + 0.2 === 0.3  // false! → 0.30000000000000004

// Why? IEEE 754 double precision can't represent 0.1 exactly

// Fix: Use integer math
const price = (0.1 * 100 + 0.2 * 100) / 100; // 0.3 ✅

// Or use toFixed for display
(0.1 + 0.2).toFixed(2); // "0.30"

// Or use a library for money: currency.js, dinero.js, decimal.js
Enter fullscreen mode Exit fullscreen mode

Useful Number Methods

// Rounding
Math.round(4.5);   // 5  (rounds to nearest, 0.5 rounds up)
Math.round(4.4);   // 4
Math.floor(4.9);   // 4  (always down)
Math.ceil(4.1);    // 5  (always up)
Math.trunc(4.9);   // 4  (remove decimal, no rounding)

// Decimal precision
(1.005).toFixed(2);  // "1.00" ❌ (wrong!)
(1.005 * 100 + Number.EPSILON).toFixed(2) / 100; // 1.01 ✅

// Random numbers
Math.random();                    // 0 to < 1
Math.floor(Math.random() * 10);  // 0 to 9
Math.floor(Math.random() * 10) + 1;  // 1 to 10
function randInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}
randInt(1, 100);  // Random integer 1-100

// Random from array
const colors = ['red', 'green', 'blue'];
colors[Math.floor(Math.random() * colors.length)];

// Shuffle array (Fisher-Yates)
function shuffle(arr) {
  const a = [...arr];
  for (let i = a.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [a[i], a[j]] = [a[j], a[i]];
  }
  return a;
}
Enter fullscreen mode Exit fullscreen mode

Number Formatting

// Currency
const price = 1234567.89;
new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(price);
// "$1,234,567.89"

new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(price);
// "¥1,234,568" (no decimals for JPY)

// Thousands separator
new Intl.NumberFormat().format(1234567);  // "1,234,567"

// Compact notation
new Intl.NumberFormat('en', { notation: 'compact' }).format(1500000);
// "1.5M"

// Percentage
new Intl.NumberFormat('en', { style: 'percent' }).format(0.85);
// "85%"

// Fixed decimals
(42).toFixed(2);     // "42.00"
(42.678).toFixed(2); // "42.68"

// Significant digits
(123456).toPrecision(3); // "1.23e+5"
(123.456).toPrecision(4); // "123.5"

// Bytes to human-readable
function formatBytes(bytes) {
  const units = ['B', 'KB', 'MB', 'GB', 'TB'];
  let i = 0;
  let size = bytes;
  while (size >= 1024 && i < units.length - 1) {
    size /= 1024;
    i++;
  }
  return `${size.toFixed(1)} ${units[i]}`;
}
formatBytes(1536);     // "1.5 KB"
formatBytes(1073741824); // "1.0 GB"
Enter fullscreen mode Exit fullscreen mode

Math Shortcuts

// Clamp a value between min and max
const clamp = (val, min, max) => Math.min(Math.max(val, min), max);
clamp(150, 0, 100);  // 100
clamp(-50, 0, 100);  // 0
clamp(50, 0, 100);   // 50

// Distance between two points
const distance = (x1, y1, x2, y2) => 
  Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);

// Linear interpolation
const lerp = (start, end, t) => start + (end - start) * t;
lerp(0, 100, 0.5);  // 50
lerp(0, 100, 0.75); // 75

// Map value from one range to another
const map = (val, inMin, inMax, outMin, outMax) =>
  outMin + (outMax - outMin) * ((val - inMin) / (inMax - inMin));
map(5, 0, 10, 0, 100);  // 50
map(3, 0, 10, -1, 1);   // -0.4

// Average
const avg = (...nums) => nums.reduce((a, b) => a + b, 0) / nums.length;
avg(1, 2, 3, 4, 5);  // 3

// Sum
const sum = (...nums) => nums.reduce((a, b) => a + b, 0);
sum(1, 2, 3, 4, 5);  // 15

// Min/Max from array
const numbers = [3, 7, 2, 9, 1, 5];
Math.min(...numbers);  // 1
Math.max(...numbers);  // 9

// GCD (Greatest Common Divisor)
const gcd = (a, b) => b === 0 ? a : gcd(b, a % b);
gcd(12, 8);  // 4

// Prime check
const isPrime = (n) => {
  if (n < 2) return false;
  for (let i = 2; i <= Math.sqrt(n); i++) {
    if (n % i === 0) return false;
  }
  return true;
};
Enter fullscreen mode Exit fullscreen mode

Bitwise Tricks

// Check if number is even/odd
5 & 1;  // 1 (odd)
4 & 1;  // 0 (even)
// Faster than n % 2 (marginally)

// Swap without temp variable
let a = 10, b = 20;
a ^= b; b ^= a; a ^= b;
// a = 20, b = 10

// Power of 2 check
const isPowerOf2 = (n) => n > 0 && (n & (n - 1)) === 0;
isPowerOf2(8);   // true
isPowerOf2(10);  // false

// Fast multiply/divide by 2
n << 1;   // n * 2
n >> 1;   // n / 2 (integer division)
Enter fullscreen mode Exit fullscreen mode

parseInt Gotchas

parseInt('123');        // 123
parseInt('123abc');     // 123 (stops at non-digit)
parseInt('abc123');     // NaN
parseInt('0xFF');       // 255 (hex)
parseInt('0o77');       // 63 (octal)
parseInt('0b1010');     // 0 (binary NOT supported without radix!)

// ⚠️ ALWAYS specify radix
parseInt('10', 10);    // 10 (decimal)
parseInt('10', 2);     // 2 (binary)
parseInt('10', 8);     // 8 (octal)
parseInt('10', 16);    // 16 (hex)
parseInt('10', 36);    // 36 (base 36)

// Number() vs parseInt()
Number('123abc');      // NaN (strict)
parseInt('123abc');     // 123 (lenient)
Number('');             // 0
parseInt('');           // NaN
Number(true);          // 1
parseInt(true);        // NaN
Enter fullscreen mode Exit fullscreen mode

Type Checking

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

Number.isInteger(42);      // true
Number.isInteger(42.0);    // true
Number.isInteger(42.5);    // false

Number.isNaN(NaN);         // true
Number.isNaN('hello');     // false (global isNaN would return true!)

Number.isSafeInteger(9007199254740991);  // true (max safe integer)
Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1);  // false
Enter fullscreen mode Exit fullscreen mode

What's your favorite number trick in JavaScript?

Follow @armorbreak for more JS content.

Top comments (0)