javascript

examples

examples.js
/**
 * 8.3 BigInt - Examples
 */

// ============================================
// CREATING BIGINT VALUES
// ============================================

console.log('=== Creating BigInt ===');

// Literal syntax (append 'n')
const bigLiteral = 123456789012345678901234567890n;
console.log('Literal:', bigLiteral);
console.log('Type:', typeof bigLiteral);

// BigInt constructor
const fromInt = BigInt(123);
console.log('From int:', fromInt);

const fromString = BigInt('9007199254740993');
console.log('From string:', fromString);

// Hex, octal, binary
const hex = BigInt('0xFF'); // 255n
const octal = BigInt('0o777'); // 511n
const binary = BigInt('0b11111111'); // 255n
console.log('Hex:', hex, 'Octal:', octal, 'Binary:', binary);

// ============================================
// WHY BIGINT? NUMBER PRECISION LIMITS
// ============================================

console.log('\n=== Number Precision Limits ===');

console.log('MAX_SAFE_INTEGER:', Number.MAX_SAFE_INTEGER);

// Precision loss with Number
const unsafeNum = 9007199254740991 + 2;
console.log('Number:', unsafeNum); // Wrong! (9007199254740992)

// Correct with BigInt
const safeBig = 9007199254740991n + 2n;
console.log('BigInt:', safeBig); // Correct! (9007199254740993n)

// Very large numbers
const huge = 2n ** 100n;
console.log('2^100:', huge);

// ============================================
// ARITHMETIC OPERATIONS
// ============================================

console.log('\n=== Arithmetic Operations ===');

const a = 10n;
const b = 3n;

console.log('a + b =', a + b); // 13n
console.log('a - b =', a - b); // 7n
console.log('a * b =', a * b); // 30n
console.log('a / b =', a / b); // 3n (truncated)
console.log('a % b =', a % b); // 1n
console.log('a ** b =', a ** b); // 1000n

// Division always truncates toward zero
console.log('\nDivision truncation:');
console.log('5n / 2n =', 5n / 2n); // 2n
console.log('-5n / 2n =', -5n / 2n); // -2n

// Negation
console.log('\nNegation:');
console.log('-a =', -a); // -10n

// ============================================
// COMPARISON OPERATIONS
// ============================================

console.log('\n=== Comparisons ===');

// With BigInt
console.log('10n > 5n:', 10n > 5n); // true
console.log('10n === 10n:', 10n === 10n); // true

// Mixed comparison (allowed)
console.log('10n > 5:', 10n > 5); // true
console.log('10n < 20:', 10n < 20); // true

// Strict vs loose equality
console.log('\nEquality:');
console.log('10n === 10:', 10n === 10); // false (different types)
console.log('10n == 10:', 10n == 10); // true (coerced)

// Sorting mixed array
const mixed = [10n, 5, 8n, 3, 12n, 1];
mixed.sort((x, y) => (x < y ? -1 : x > y ? 1 : 0));
console.log('Sorted:', mixed);

// ============================================
// TYPE CONVERSION
// ============================================

console.log('\n=== Type Conversion ===');

const big = 123n;

// To Number
console.log('Number(123n):', Number(big));

// To String
console.log('String(123n):', String(big));
console.log('toString(16):', big.toString(16)); // hex
console.log('toString(2):', big.toString(2)); // binary

// To Boolean
console.log('Boolean(0n):', Boolean(0n)); // false
console.log('Boolean(1n):', Boolean(1n)); // true

// Number to BigInt (must be integer)
console.log('\nNumber to BigInt:');
console.log('BigInt(123):', BigInt(123));
// BigInt(1.5);  // TypeError!
console.log('BigInt(Math.trunc(1.9)):', BigInt(Math.trunc(1.9)));

// ============================================
// CANNOT MIX OPERATIONS
// ============================================

console.log('\n=== Cannot Mix Types ===');

const bigVal = 10n;
const numVal = 5;

// This would throw: bigVal + numVal

// Must convert explicitly
console.log('BigInt + BigInt:', bigVal + BigInt(numVal)); // 15n
console.log('Number + Number:', Number(bigVal) + numVal); // 15

// Math object doesn't work with BigInt
// Math.sqrt(4n);  // TypeError
console.log('Manual sqrt:', 4n ** 1n); // Can do simple operations

// ============================================
// BITWISE OPERATIONS
// ============================================

console.log('\n=== Bitwise Operations ===');

const x = 0b1010n; // 10n
const y = 0b1100n; // 12n

console.log('x & y (AND):', x & y); // 8n (0b1000)
console.log('x | y (OR):', x | y); // 14n (0b1110)
console.log('x ^ y (XOR):', x ^ y); // 6n (0b0110)
console.log('~x (NOT):', ~x); // -11n

console.log('\nShift operations:');
console.log('x << 2n:', x << 2n); // 40n
console.log('x >> 1n:', x >> 1n); // 5n

// Large bitwise operations
const large = 1n << 64n;
console.log('1n << 64n:', large);

// ============================================
// JSON SERIALIZATION
// ============================================

console.log('\n=== JSON Serialization ===');

const data = {
  id: 123456789012345678901n,
  name: 'test',
};

// Default JSON.stringify fails
try {
  JSON.stringify(data);
} catch (e) {
  console.log('Default error:', e.message);
}

// Custom serialization
const jsonString = JSON.stringify(data, (key, value) =>
  typeof value === 'bigint' ? value.toString() + 'n' : value
);
console.log('Custom JSON:', jsonString);

// Custom parsing
const parsed = JSON.parse(jsonString, (key, value) => {
  if (typeof value === 'string' && value.endsWith('n')) {
    return BigInt(value.slice(0, -1));
  }
  return value;
});
console.log('Parsed back:', parsed.id, typeof parsed.id);

// ============================================
// PRACTICAL: DATABASE IDS
// ============================================

console.log('\n=== Database IDs ===');

// Twitter-style snowflake IDs (64-bit)
const snowflakeId = BigInt('1309881276729737216');
console.log('Snowflake ID:', snowflakeId);

// Parse snowflake (Twitter format)
function parseSnowflake(id) {
  const snowflake = BigInt(id);
  const timestamp = (snowflake >> 22n) + 1288834974657n;
  return {
    timestamp: new Date(Number(timestamp)),
    workerId: Number((snowflake & 0x3e0000n) >> 17n),
    processId: Number((snowflake & 0x1f000n) >> 12n),
    sequence: Number(snowflake & 0xfffn),
  };
}

console.log('Parsed:', parseSnowflake(snowflakeId));

// ============================================
// PRACTICAL: FINANCIAL CALCULATIONS
// ============================================

console.log('\n=== Financial Calculations ===');

class Money {
  constructor(cents) {
    this.cents = BigInt(cents);
  }

  add(other) {
    return new Money(this.cents + other.cents);
  }

  subtract(other) {
    return new Money(this.cents - other.cents);
  }

  multiply(factor) {
    return new Money(this.cents * BigInt(factor));
  }

  divide(divisor) {
    return new Money(this.cents / BigInt(divisor));
  }

  format() {
    const str = this.cents.toString().padStart(3, '0');
    const dollars = str.slice(0, -2) || '0';
    const cents = str.slice(-2);
    return `$${dollars}.${cents}`;
  }
}

const price = new Money(2999); // $29.99
const quantity = 1000000;
const total = price.multiply(quantity);
console.log(`${quantity} items at ${price.format()} = ${total.format()}`);

// ============================================
// PRACTICAL: CRYPTOGRAPHY
// ============================================

console.log('\n=== Cryptography Example ===');

// Modular exponentiation (for RSA-like operations)
function modPow(base, exponent, mod) {
  let result = 1n;
  base = base % mod;
  while (exponent > 0n) {
    if (exponent % 2n === 1n) {
      result = (result * base) % mod;
    }
    exponent = exponent / 2n;
    base = (base * base) % mod;
  }
  return result;
}

const base = 7n;
const exp = 256n;
const mod = 13n;
console.log(`${base}^${exp} mod ${mod} =`, modPow(base, exp, mod));

// Large prime check (simple)
function isProbablyPrime(n, k = 5) {
  if (n < 2n) return false;
  if (n === 2n) return true;
  if (n % 2n === 0n) return false;

  // Simple trial division for demo
  for (let i = 3n; i * i <= n; i += 2n) {
    if (n % i === 0n) return false;
  }
  return true;
}

console.log('Is 104729 prime?', isProbablyPrime(104729n));

// ============================================
// PRACTICAL: TIMESTAMPS
// ============================================

console.log('\n=== Nanosecond Timestamps ===');

// High-precision timestamp
const timestampNs = 1234567890123456789n;

const seconds = timestampNs / 1000000000n;
const nanos = timestampNs % 1000000000n;

console.log('Timestamp (ns):', timestampNs);
console.log('Seconds:', seconds);
console.log('Nanoseconds:', nanos);

// Create from current time
const nowNs = BigInt(Date.now()) * 1000000n;
console.log('Current time (ns):', nowNs);

// ============================================
// PRACTICAL: FACTORIAL
// ============================================

console.log('\n=== Large Factorial ===');

function factorial(n) {
  let result = 1n;
  for (let i = 2n; i <= BigInt(n); i++) {
    result *= i;
  }
  return result;
}

console.log('50! =', factorial(50));
console.log('100! digit count:', factorial(100).toString().length);

// ============================================
// PRACTICAL: FIBONACCI
// ============================================

console.log('\n=== Large Fibonacci ===');

function fibonacci(n) {
  if (n <= 1) return BigInt(n);
  let a = 0n,
    b = 1n;
  for (let i = 2; i <= n; i++) {
    [a, b] = [b, a + b];
  }
  return b;
}

console.log('Fibonacci(100):', fibonacci(100));
console.log('Fibonacci(1000) digits:', fibonacci(1000).toString().length);

console.log('\n=== Examples Complete ===');
Examples - JavaScript Tutorial | DeepML