Lesson 6: Mastering JavaScript Numbers, BigInt, and Precision, NAN and more with challenges!

manoj ymkmanoj ymk
7 min read

πŸ“ BigInt: Handling Large Integers

JavaScript's Number type can safely represent integers up to 2^53 - 1 (Number.MAX_SAFE_INTEGER). Beyond this, precision issues arise. Enter BigInt, a numeric type that can represent integers of arbitrary size.​

Creating BigInts:

const big1 = 1234567890123456789012345678901234567890n; // Literal syntax
const big2 = BigInt("1234567890123456789012345678901234567890"); // Constructor

Key Characteristics:

  • Arithmetic Operations: Use standard operators (+, -, *, /, %), but both operands must be BigInt.​
  10n + 20n; // 30n
  5n / 2n;   // 2n (truncates towards zero)
1n + 2; // TypeError
  • Conversions:

    • Number(bigIntValue) may lead to precision loss if the BigInt exceeds Number.MAX_SAFE_INTEGER.​

    • BigInt(numberValue) works if numberValue is an integer.​

  • Serialization: BigInt cannot be serialized to JSON directly.​MDN Web Docs

  JSON.stringify({ value: 10n }); // TypeError
  // Workaround:
  JSON.stringify({ value: 10n.toString() });
  • Limitations:

    • Cannot use Math methods with BigInt.​

    • No support for decimal points.​

    • Unary plus (+bigInt) is not supported.​

πŸ” Object.is(): Precise Value Comparison

Object.is() determines whether two values are the same value. It is similar to the strict equality operator (===), but with some differences:​MDN Web Docs

  • Object.is(+0, -0) returns false, whereas +0 === -0 is true.​

  • Object.is(NaN, NaN) returns true, whereas NaN === NaN is false.​

Examples:

Object.is(NaN, NaN);    // true
Object.is(+0, -0);      // false
Object.is(0, -0);       // false
Object.is(1, 1);        // true
Object.is({}, {});      // false (different object references)

πŸ”’ Rounding and Precision

JavaScript uses IEEE 754 double-precision floating-point numbers, which can lead to precision issues:​

0.1 + 0.2 === 0.3; // false

Rounding Methods:

javascriptCopyEdit  (0.1 + 0.2).toFixed(2); // "0.30"

Workarounds for Precision Issues:

  • Use toFixed() for rounding and then convert back to number:​
 parseFloat((0.1 + 0.2).toFixed(10)) === 0.3; // true
  • Use integer arithmetic when dealing with currency:​
  // Represent $0.30 as 30 cents
  10 + 20 === 30; // true

πŸ§ͺ Type Checking Functions

isNaN() vs. Number.isNaN():

  • isNaN(value): Converts the value to a number and checks if it's NaN.​
isNaN("abc"); // true
  • Number.isNaN(value): Checks if the value is strictly NaN without coercion.​
  Number.isNaN("abc"); // false
  Number.isNaN(NaN);   // true

isFinite() vs. Number.isFinite():

  • isFinite(value): Converts the value to a number and checks if it's finite.​
  isFinite("10"); // true
  • Number.isFinite(value): Checks if the value is a number and finite without coercion.​MDN Web Docs
  Number.isFinite("10"); // false
  Number.isFinite(10);   // true

πŸ”Ή 2. Fill Any Gaps β€” Advanced Insights, Internal Mechanics, and Pitfalls

⚠️ Common Pitfalls and Edge Cases

1. BigInt & Number Mixing = 🚨 TypeError

console.log(1n + 1); // ❌ TypeError: Cannot mix BigInt and other types

βœ… Instead, explicitly convert:

console.log(1n + BigInt(1));      // 2n
console.log(Number(1n) + 1);      // 2

2. BigInt in JSON = ❌ Not Serializable

JSON.stringify({ value: 123n }); // ❌ TypeError

βœ… Use .toString() or a replacer:

JSON.stringify({ value: 123n.toString() }); // βœ…

3. Floating-Point Arithmetic Precision

Due to IEEE 754, many devs mistakenly trust this:

0.1 + 0.2 === 0.3; // ❌ false

βœ… Use rounding:

Math.abs((0.1 + 0.2) - 0.3) < Number.EPSILON; // βœ… true

4. Object.is() Differences

Object.is(+0, -0); // false ❗
+0 === -0;         // true

Object.is(NaN, NaN); // true ❗
NaN === NaN;         // false

➑️ Use Object.is() in polyfills or for corner-case comparisons.

5. toFixed() Returns a String

typeof (1.2345).toFixed(2); // "string"

🧠 Pro Tip: Wrap with parseFloat() if you need a number.

6. Math.round() & Banker's Rounding

JavaScript uses round half up, not banker’s rounding:

Math.round(2.5); // 3
Math.round(-2.5); // -2

πŸ”Ή 3. Challenge Me Deeply β€” 10 Problems + 1 β€œAha!” Twister

🟒 Basic

  1. Check BigInt Limits
    Write a function that checks if a number exceeds Number.MAX_SAFE_INTEGER and converts it to BigInt safely.

  2. Object.is Checker
    Implement a custom isSameValue(x, y) that mimics Object.is() using only basic operators.

  3. Round Me Right
    Write a utility function smartRound(value, digits) that rounds a number and returns a number (not string).

🟑 Intermediate

  1. Currency Formatter
    Build a function that takes a float (e.g., 19.899) and returns a formatted INR string like β‚Ή19.90, using toFixed().

  2. NaN Validator
    Write a function that returns true only if input is actual NaN, and false for anything else β€” without using isNaN() or Number.isNaN().

  3. Safe Summation
    Sum a list of prices like [0.1, 0.2, 0.3] accurately. Avoid floating-point precision errors.

  4. BigInt Multiplication Table
    Print the multiplication table of a BigInt from 1n to 10n.

πŸ”΄ Advanced

  1. BigInt Safe Parser
    Write a function that parses very large integers from string input and performs math like addition/division safely.

  2. Dynamic Rounding Rules
    Given an input with rounding rules (round up, floor, truncate), apply correct rounding method dynamically.

  3. Precision Loss Detector
    Detect if a given number loses precision when converted from BigInt β†’ Number.

πŸ’‘ Aha! Brain Twister

  1. Guess the Output
console.log(Object.is(NaN, NaN));       // ?
console.log(Object.is(+0, -0));         // ?
console.log((0.1 + 0.2).toFixed(2));    // ?
console.log(9007199254740991 + 1);      // ?
console.log(9007199254740991 + 2);      // ?

(Write down expected values, then verify!)


πŸ”Ή 4. Interview-Ready Questions

πŸ“˜ Concept-Based

  • What is the difference between Object.is(), ===, and ==?

  • How does BigInt differ from Number internally and syntactically?

  • Why does (0.1 + 0.2) !== 0.3 in JavaScript?

🧩 Scenario-Based

  • How would you ensure currency accuracy in an e-commerce app?

  • How would you store a user's Aadhaar number (12+ digit integer) safely in JavaScript?

🐞 Debugging Style

  • A function returns true for isNaN("Hello") β€” what’s wrong?

  • Why does your API return "100.00" instead of a number?

βœ… Best Practices

πŸ‘ Do:

  • Use BigInt for large integer-only domains (cryptography, finance).

  • Use toFixed() + parseFloat() for user-facing rounded numbers.

  • Use Object.is() for edge-case comparisons.

🚫 Avoid:

  • Mixing BigInt with Number without conversion.

  • Trusting == or === to compare NaN.

  • Assuming JSON can serialize BigInt.


πŸ”Ή 5. Real-World Usage

πŸ“¦ Front-End

  • Currency formatting (toFixed, rounding).

  • UI display of prices, ratings, or scores.

  • Displaying long IDs or account numbers using BigInt.

🌐 Back-End (Node.js)

  • Dealing with cryptographic values, blockchain transaction IDs (BigInt).

  • Big financial data β€” no floating point allowed.

πŸ› οΈ Frameworks/Libraries

  • Lodash: has utilities for precision-safe rounding.

  • BN.js / Big.js: used for BigInt support before native BigInt arrived.

  • Intl.NumberFormat: modern API for formatting numbers/currencies.


πŸ”Ή 6. Remember Like a Pro

🧠 Mnemonics & Visuals

  • Object.is() is like === on steroids: remembers NaN β‰  NaN and +0 β‰  -0.

  • BigInt = Big Integer (No fractions, no decimal).

  • isNaN is loose, Number.isNaN is strict.

🧾 Cheatsheet

Comparison=====Object.is()
NaNfalsefalseβœ… true
+0 vs -0truetrue❌ false
1 vs 1truetrueβœ… true
{} vs {}falsefalse❌ false
Rounding FunctionEffect
Math.round(x)Nearest integer
Math.floor(x)Rounds down
Math.ceil(x)Rounds up
Math.trunc(x)Removes decimals
x.toFixed(n)Rounds and fixes decimals

πŸ”Ή 7. Apply It in a Fun Way β€” Mini Project Idea

πŸ’‘ Currency Calculator (INR)

Goal: Build a utility to sum item prices like β‚Ή99.99 + β‚Ή10.25 + β‚Ή15.50 and return a properly formatted total with accurate rounding.

πŸ›  Steps:

  1. Accept a list of prices as floats.

  2. Convert all to cents (integers): β‚Ή99.99 β†’ 9999.

  3. Sum in integers.

  4. Convert back to float with .toFixed(2).

  5. Format the output as β‚ΉXXX.XX.

βž• Bonus Extensions:

  • Support BigInt mode for super-high value transactions.

  • Add currency switcher (INR, USD, EUR) using Intl.NumberFormat.


🧠 (Optional) Extra Value

🧩 Open Source Usage:

  • Ethereum/Web3 DApps: Use BigInt for large balances.

  • Finance Libraries: Use toFixed, BigInt, Math for accurate rounding.

  • Crypto APIs: Use BN.js, bignumber.js.

⚠️ Common Dev Mistakes

  • Using === to compare NaN.

  • Assuming +0 === -0 implies they're the same value.

  • Forgetting toFixed() returns a string.

  • Using JSON.stringify() directly on BigInt.

⚑ Performance Tips

  • Avoid excessive type conversions (BigInt <-> Number).

  • Round early when working with floats to reduce propagation error.

0
Subscribe to my newsletter

Read articles from manoj ymk directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

manoj ymk
manoj ymk