Numbers, Math & BigInt

কেন 0.1 + 0.2 ≠ 0.3 — এবং তার সমাধান

~30 min Intermediate 12 practice problems Live runner

1. JavaScript Has One Number Type

Unlike C or Java, JS doesn't separate int and float. Every number is a 64-bit IEEE 754 double-precision float. That gives ~15–17 decimal digits of precision and a range from about 5e-324 to 1.79e308.

JS-এ আলাদা int/float নেই — প্রতিটি number একটি ৬৪-bit double-precision float। প্রায় ১৫-১৭ digit precision পাওয়া যায়। বড় integer-এর জন্য আছে BigInt।

2. The 0.1 + 0.2 Surprise

Decimal fractions like 0.1 can't be represented exactly in binary floats — just as 1/3 can't be represented exactly in decimal. The error is tiny but real.

float.js
console.log(0.1 + 0.2);              // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3);       // false

// Safe equality with epsilon
const nearlyEqual = (a, b) =>
    Math.abs(a - b) < Number.EPSILON * Math.max(1, Math.abs(a), Math.abs(b));
console.log(nearlyEqual(0.1 + 0.2, 0.3)); // true

// Practical fix: round to fixed decimals
console.log((0.1 + 0.2).toFixed(2));      // "0.30"
console.log(+(0.1 + 0.2).toFixed(2));     // 0.3
Money rule Never store currency as a float. Use integer cents (1099 = ৳10.99) or a dedicated decimal library.

3. The Math Object

math.js
console.log(Math.PI);           // 3.1415...
console.log(Math.E);            // 2.7182...
console.log(Math.floor(4.7));    // 4
console.log(Math.ceil(4.1));     // 5
console.log(Math.round(4.5));    // 5
console.log(Math.trunc(-4.7));   // -4 (toward zero)
console.log(Math.abs(-7));       // 7
console.log(Math.sqrt(144));     // 12
console.log(Math.cbrt(27));      // 3
console.log(Math.pow(2, 10));    // 1024
console.log(Math.min(5, 2, 9));   // 2
console.log(Math.max(5, 2, 9));   // 9
console.log(Math.random());      // [0, 1)

// Random integer in [min, max]
const randInt = (min, max) =>
    Math.floor(Math.random() * (max - min + 1)) + min;
console.log(randInt(1, 6));    // dice roll

4. Parsing & Validating Numbers

parse.js
console.log(Number("42"));               // 42
console.log(Number("42.5"));             // 42.5
console.log(Number("42px"));             // NaN  ← strict
console.log(parseInt("42px", 10));        // 42   ← lenient
console.log(parseFloat("3.14ka"));        // 3.14

// ALWAYS pass radix to parseInt
console.log(parseInt("0x1F", 16));       // 31
console.log(parseInt("101", 2));         // 5  (binary)

console.log(Number.isNaN(NaN));            // true
console.log(Number.isNaN("hi"));           // false ← strict
console.log(isNaN("hi"));                  // true  ← coerces, avoid
console.log(Number.isFinite(1 / 0));         // false
console.log(Number.isInteger(5.0));         // true

5. Safe Integer Range & BigInt

Doubles can represent integers exactly only up to 2^53 − 1. Beyond that, neighbouring integers collapse onto the same float. Use BigInt when accuracy matters.

bigint.js
console.log(Number.MAX_SAFE_INTEGER);     // 9007199254740991
console.log(9007199254740993);              // 9007199254740992  ← lost!

console.log(9007199254740993n);             // 9007199254740993n   exact
console.log(10n ** 30n);                   // 1000...0n  (30 zeros)

// You CANNOT mix BigInt with Number
try { console.log(1n + 1); }
catch (e) { console.log("err:", e.message); }

console.log(1n + BigInt(1));               // 2n
console.log(typeof 1n);                  // "bigint"

6. Locale-Aware Number Formatting

Intl.NumberFormat formats numbers per region — comma vs lakh-style, currency symbols, percentages, and Bangla digits.

intl.js
const n = 1234567.89;

console.log(new Intl.NumberFormat("en-US").format(n));
// "1,234,567.89"

console.log(new Intl.NumberFormat("en-IN").format(n));
// "12,34,567.89"  ← Indian/Bangladeshi grouping

console.log(new Intl.NumberFormat("bn-BD", {
    style: "currency", currency: "BDT"
}).format(n));
// "১২,৩৪,৫৬৭.৮৯ ৳"

console.log(new Intl.NumberFormat("en", {
    style: "percent", minimumFractionDigits: 1
}).format(0.0734));
// "7.3%"

7. Glossary (শব্দকোষ)

TermMeaningবাংলায়
IEEE 754The floating-point standard JS uses for every number.প্রতিটি JS number যে floating-point standard মেনে চলে।
Floating pointBinary representation that can't store every decimal exactly.Binary representation — প্রতিটি দশমিক exact-ভাবে রাখতে পারে না।
PrecisionHow many significant digits can be represented (~15-17).কতগুলো অর্থপূর্ণ digit সংরক্ষণ করা যায় (~১৫-১৭)।
NaN"Not a Number" — result of invalid math; type is number.অবৈধ math-এর ফলাফল; type হলেও "number"।
InfinityResult of dividing a positive number by 0.1/0-এর মতো অপারেশনের ফলাফল।
BigIntArbitrary-precision integer type, written with n suffix.যেকোনো বড় integer — শেষে n লাগে।
RadixThe base in parseInt(str, radix) — 10 for decimal.parseInt-এর base; দশমিকের জন্য 10।
Number.EPSILONSmallest difference between distinct numbers near 1.1-এর কাছাকাছি দুটি ভিন্ন number-এর সবচেয়ে ছোট পার্থক্য।
Intl.NumberFormatLocale-aware number formatting (currency, percent, BD digits).Locale অনুযায়ী number format — currency, percent, Bangla digit।
মূল কথা: JS-এ একটিই number type — IEEE 754 double। দশমিক exact নয়, তাই 0.1 + 0.2 ≠ 0.3। Money-তে কখনোই float নয় — paisa/cent integer-এ রাখুন বা decimal library ব্যবহার করুন। বড় integer-এ BigInt; locale-aware formatting-এ Intl.NumberFormat। parseInt-এ সবসময় radix দিন।

8. Practice Problems

  1. Show that 0.1 + 0.2 !== 0.3 and produce a correct equality check.
    ✨ Show Answer
    a1.js
    console.log(0.1 + 0.2);
    console.log(Math.abs((0.1 + 0.2) - 0.3) < Number.EPSILON);
  2. Round 3.456 to 2 decimal places.
    ✨ Show Answer
    a2.js
    console.log((3.456).toFixed(2));   // "3.46"
    console.log(Math.round(3.456 * 100) / 100); // 3.46
  3. Generate a random integer between 1 and 100 (inclusive).
    ✨ Show Answer
    a3.js
    const r = Math.floor(Math.random() * 100) + 1;
    console.log(r);
  4. Convert hex string "FF" to decimal.
    ✨ Show Answer
    a4.js
    console.log(parseInt("FF", 16));   // 255
  5. Find the maximum of an array of numbers without using a loop.
    ✨ Show Answer
    a5.js
    const arr = [12, 5, 99, 3, 71];
    console.log(Math.max(...arr)); // 99
  6. Compute factorial of 25 with BigInt.
    ✨ Show Answer
    a6.js
    let f = 1n;
    for (let i = 2n; i <= 25n; i++) f *= i;
    console.log(f);   // 15511210043330985984000000n
  7. Format 1234567.89 as Bangladesh currency.
    ✨ Show Answer
    a7.js
    console.log(new Intl.NumberFormat("bn-BD",
        { style: "currency", currency: "BDT" }).format(1234567.89));
  8. Why does Number("42px") give NaN but parseInt("42px", 10) gives 42?
    ✨ Show Answer

    Answer: Number() requires the entire string to be a valid number; any stray character makes the result NaN. parseInt walks the string left-to-right and stops at the first non-digit, returning whatever it parsed so far. Choose Number() when you want strictness, parseInt when you want lenience.

  9. Implement a coin-flip function that returns "heads" or "tails".
    ✨ Show Answer
    a9.js
    const flip = () => Math.random() < 0.5 ? "heads" : "tails";
    console.log(Array.from({ length: 5 }, flip));
  10. Convert temperature 36.6°C to Fahrenheit.
    ✨ Show Answer
    a10.js
    const c = 36.6;
    const f = c * 9 / 5 + 32;
    console.log(f.toFixed(1) + "°F"); // "97.9°F"
  11. Why does Math.max() with no arguments return -Infinity?
    ✨ Show Answer

    Answer: The identity element for max is -Infinity — the smallest possible value, so anything you compare to it will be larger. By analogy, Math.min() returns +Infinity. This makes Math.max work correctly when used with reduce on an empty array.

  12. Print all integers from 1 to 10 in their Bangla numeric form.
    ✨ Show Answer
    a12.js
    const fmt = new Intl.NumberFormat("bn-BD");
    for (let i = 1; i <= 10; i++) console.log(fmt.format(i));

Summary — Module 08

Numbers in JS are 64-bit IEEE 754 doubles. Decimal arithmetic isn't exact — never use floats for money. The Math object covers most operations; BigInt handles arbitrary-precision integers; Intl.NumberFormat handles locale-aware display. Always pass a radix to parseInt.

JS-এ একটিই number type — IEEE 754 double। দশমিক arithmetic exact নয় — money-তে কখনো float ব্যবহার করবেন না। বড় integer-এ BigInt, formatting-এ Intl.NumberFormat।

Next Module → Control Flow — if, switch, ternary।