JavaScript Numbers
Numbers in JavaScript are a fundamental data type used to represent numeric values. JavaScript numbers are double-precision 64-bit binary format IEEE 754 values. This means they are floating-point numbers, and there is only one number type in JavaScript for both integers and floating-point numbers.
Concept and Use Cases
Definition:
A number in JavaScript is an immutable numeric data type used to perform arithmetic operations. JavaScript numbers can be integers, floating-point numbers, and special numeric values like Infinity, -Infinity, and NaN (Not-a-Number).
Common Use Cases:
- Performing arithmetic calculations.
- Representing and manipulating date and time.
- Working with user input that involves numeric data.
- Implementing algorithms that require numerical computation.
When to Use
- When performing mathematical calculations.
- When working with any form of numerical data.
- When needing to represent and manipulate dates and times.
Time and Space Complexity
Time Complexity:
- Arithmetic operations (addition, subtraction, multiplication, division): O(1)
- Parsing numbers from strings: O(n) (where n is the length of the string)
- Converting numbers to strings: O(n) (where n is the number of digits)
Space Complexity:
- Depends on the representation of the number. Typically, it's constant space for individual numbers.
Number Operations and Methods
Creating Numbers
Example:
let integer = 42;
let float = 3.14;
let negative = -1;
let scientific = 1.23e5; // 123000
let hex = 0xff; // 255
Basic Arithmetic
Example:
let a = 10;
let b = 3;
console.log(a + b); // Output: 13
console.log(a - b); // Output: 7
console.log(a * b); // Output: 30
console.log(a / b); // Output: 3.3333333333333335
console.log(a % b); // Output: 1
Math Object Methods
Example:
console.log(Math.PI); // Output: 3.141592653589793
console.log(Math.E); // Output: 2.718281828459045
console.log(Math.abs(-10)); // Output: 10
console.log(Math.pow(2, 3)); // Output: 8
console.log(Math.sqrt(16)); // Output: 4
console.log(Math.round(4.6)); // Output: 5
console.log(Math.ceil(4.2)); // Output: 5
console.log(Math.floor(4.8)); // Output: 4
console.log(Math.min(1, 2, 3)); // Output: 1
console.log(Math.max(1, 2, 3)); // Output: 3
console.log(Math.random()); // Output: Random number between 0 and 1
Special Numeric Values
Example:
console.log(Infinity); // Output: Infinity
console.log(-Infinity); // Output: -Infinity
console.log(NaN); // Output: NaN
console.log(isNaN(NaN)); // Output: true
console.log(isFinite(42)); // Output: true
console.log(isFinite(Infinity)); // Output: false
Type Conversion
Example:
let str = '123';
let num = Number(str);
console.log(num); // Output: 123
let strFloat = '123.45';
let floatNum = parseFloat(strFloat);
console.log(floatNum); // Output: 123.45
let strInt = '123.45';
let intNum = parseInt(strInt);
console.log(intNum); // Output: 123
Number Formatting
Example:
let num = 12345.6789;
console.log(num.toFixed(2)); // Output: '12345.68'
console.log(num.toPrecision(5)); // Output: '12346'
console.log(num.toExponential(2)); // Output: '1.23e+4'
console.log(num.toLocaleString()); // Output: '12,345.679' (varies by locale)
Practical Tips and Tricks
-
Using
Math.roundfor Rounding: When you need to round a number to the nearest integer.Example:
let num = 4.5; console.log(Math.round(num)); // Output: 5 -
Using
Math.ceilfor Rounding Up: When you need to round a number up to the nearest integer.Example:
let num = 4.1; console.log(Math.ceil(num)); // Output: 5 -
Using
Math.truncfor Truncating: When you need to remove the fractional part of a number, effectively rounding towards zero.Example:
let num = 4.9; console.log(Math.trunc(num)); // Output: 4 let numNegative = -4.9; console.log(Math.trunc(numNegative)); // Output: -4 -
Generating Random Integers: Use
Math.randomin combination withMath.floorto generate random integers within a specific range.Example:
function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } console.log(getRandomInt(1, 10)); // Output: Random integer between 1 and 10 -
Precision Issues with Floating-Point Arithmetic: Be aware of precision issues when working with floating-point numbers.
Example:
let a = 0.1; let b = 0.2; console.log(a + b); // Output: 0.30000000000000004 -
Avoiding
parseIntwith Leading Zeros:parseIntinterprets leading zeros as octal numbers in some cases. Use the radix parameter. Example:console.log(parseInt('010')); // Output: 10 (modern JavaScript) console.log(parseInt('010', 10)); // Output: 10 (explicit base 10)
Common Gotchas
-
NaN Propagation: Any arithmetic operation with
NaNresults inNaN.Example:
let result = NaN + 5; console.log(result); // Output: NaN -
Precision Errors: Floating-point arithmetic can lead to precision errors.
Example:
console.log(0.1 + 0.2 === 0.3); // Output: false -
Type Coercion: JavaScript implicitly converts types in some cases, which can lead to unexpected results.
Example:
console.log('5' - 3); // Output: 2 console.log('5' + 3); // Output: '53' -
Infinity and Division by Zero: Dividing by zero results in
Infinityor-Infinity.Example:
console.log(1 / 0); // Output: Infinity console.log(-1 / 0); // Output: -Infinity
Advanced Topics
BigInt
BigInt is a special numeric type that provides support for integers of arbitrary length. It can be used when integers larger than 2^53 - 1 are needed.
Example:
let bigInt = 1234567890123456789012345678901234567890n;
console.log(bigInt); // Output: 1234567890123456789012345678901234567890n
let anotherBigInt = BigInt('1234567890123456789012345678901234567890');
console.log(anotherBigInt); // Output: 1234567890123456789012345678901234567890n
let sum = bigInt + anotherBigInt;
console.log(sum); // Output: 2469135780246913578024691357802469135780n
Binary, Octal, and Hexadecimal Literals
JavaScript supports binary (0b), octal (0o), and hexadecimal (0x) literals for easier representation of these bases.
Example:
let binary = 0b1010; // 10
let octal = 0o12; // 10
let hex = 0xA; // 10
console.log(binary, octal, hex); // Output: 10 10 10
Number Object Methods
JavaScript provides several useful methods for the Number object.
Example:
console.log(Number.isFinite(123)); // Output: true
console.log(Number.isNaN(NaN)); // Output: true
console.log(Number.isInteger(123.4)); // Output: false
console.log(Number.parseFloat('123.45')); // Output: 123.45
console.log(Number.parseInt('123.45')); // Output: 123
Handling Precision with toFixed and toPrecision
Example:
let num = 123.456;
console.log(num.toFixed(2)); // Output: '123.46'
console.log(num.toPrecision(4)); // Output: '123.5'
Number Algorithms
Below are some common number algorithms you should be familiar with:
Finding the Greatest Common Divisor (GCD)
The GCD of two numbers is the largest number that divides both of them without leaving a remainder.
Example:
function gcd(a, b) {
while (b !== 0) {
let temp = b;
b = a % b;
a = temp;
}
return a;
}
console.log(gcd(48, 18)); // Output: 6
Prime Number Check
A prime number check determines if a number is a prime, which means it is greater than 1 and has no divisors other than 1 and itself.
Example:
function isPrime(num) {
if (num <= 1) return false;
if (num <= 3) return true;
if (num % 2 === 0 || num % 3 === 0) return false;
for (let i = 5; i * i <= num; i += 6) {
if (num % i === 0 || num % (i + 2) === 0) return false;
}
return true;
}
console.log(isPrime(11)); // Output: true
console.log(isPrime(15)); // Output: false
Generating Fibonacci Numbers
Generating Fibonacci numbers involves creating a sequence where each number is the sum of the two preceding ones.
Example:
function fibonacci(n) {
if (n <= 1) return n;
let fib = [0, 1];
for (let i = 2; i <= n; i++) {
fib[i] = fib[i - 1] + fib[i - 2];
}
return fib[n];
}
console.log(fibonacci(10)); // Output: 55
Factorial Calculation
Calculating the factorial of a number involves multiplying the number by all positive integers less than it.
Example:
function factorial(n) {
if (n === 0 || n === 1) return 1;
return n * factorial(n - 1);
}
console.log(factorial(5)); // Output: 120
Interview Tips and Tricks
-
Understand Floating-Point Arithmetic: Be aware of precision issues with floating-point numbers and know how to handle them.
-
Practice Type Conversion: Be comfortable with converting between strings and numbers, and understand the nuances of
parseInt,parseFloat, andNumber. -
Master Common Algorithms: Familiarize yourself with common number algorithms such as GCD, prime checking, Fibonacci generation, and factorial calculation. These are frequently asked in interviews.
-
Edge Cases: Always consider edge cases such as very large numbers, very small numbers, and special values like
NaN,Infinity, and-Infinity.
Common Mistakes
-
Ignoring Precision Issues: Overlooking precision problems in floating-point arithmetic can lead to incorrect results.
-
Type Coercion Pitfalls: Misunderstanding JavaScript's type coercion rules can result in unexpected behavior.
-
Using
parseIntWithout Radix: Forgetting to specify the radix forparseIntcan cause problems with leading zeros. -
Assuming All Numbers Are Safe Integers: JavaScript numbers can only safely represent integers in the range of
-(2^53 - 1)to(2^53 - 1). UseBigIntfor larger integers.
By mastering JavaScript numbers and understanding their intricacies, you will be well-equipped to handle a variety of interview questions and real-world problems involving numerical computations. Regular practice and a solid grasp of advanced topics will deepen your understanding and improve your problem-solving skills.
Practice Problems
Determine whether an integer is equal to its reverse, also known as a palindrome number.
function isPalindrome(x: number): boolean {
if (x < 0 || (x > 0 && x % 10 === 0)) {
return false;
}
let y = 0;
for (; y < x; x = ~~(x / 10)) {
y = y * 10 + (x % 10);
}
return x === y || x === ~~(y / 10);
}
Convert an integer into its corresponding Roman numeral representation using a mapping of numbers to their respective Roman symbols and handling cases where the number is less than 1 or greater than 3999.
function intToRoman(num: number): string {
const cs: string[] = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'];
const vs: number[] = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
const ans: string[] = [];
for (let i = 0; i < vs.length; ++i) {
while (num >= vs[i]) {
num -= vs[i];
ans.push(cs[i]);
}
}
return ans.join('');
}
Given a set of ugly numbers, find the smallest number that is not divisible by any of the given numbers.
function nthSuperUglyNumber(n: number, primes: number[]): number {
const uglyNumbers: number[] = [1];
const indices = new Array(primes.length).fill(0);
const nextMultiples = [...primes];
for (let count = 1; count < n; count++) {
const nextUglyNumber = Math.min(...nextMultiples);
uglyNumbers.push(nextUglyNumber);
for (let j = 0; j < primes.length; j++) {
if (nextMultiples[j] === nextUglyNumber) {
indices[j]++;
nextMultiples[j] = uglyNumbers[indices[j]] * primes[j];
}
}
}
return uglyNumbers[n - 1];
}
Find the number of trailing zeroes in the factorial of a given integer, which is determined by the count of factors of 5 in the numbers from 1 to that integer.
function trailingZeroes(n: number): number {
let ans = 0;
while (n > 0) {
n = Math.floor(n / 5);
ans += n;
}
return ans;
}
Given an integer, find the maximum number of ways to break down the integer into a product of two positive integers.
function integerBreak(n: number): number {
if (n < 4) {
return n - 1;
}
const m = Math.floor(n / 3);
if (n % 3 == 0) {
return 3 ** m;
}
if (n % 3 == 1) {
return 3 ** (m - 1) * 4;
}
return 3 ** m * 2;
}
Let's continue exploring the next page. Take your time, and proceed when you're ready.