JS Numbers

Working with Numbers

JavaScript supports integer and floating-point numbers that can be represented by decimal, hexadecimal or octal notation. JavaScript does not treat integer and floating point numbers differently than other languages. The floating-point number is represented in JavaScript as all the numbers. Here's an example to illustrate the numbers in different formats:

var x = 2;  // integer number
var y = 3.14;  // floating-point number
var z = 0xff;  // hexadecimal number

Very large numbers can be shown in exponential form, like 6.02e+23 (which is equivalent to 6.02 times 10 raised to the power of 23).

var x = 1.57e4;  // same as 15700
var y = 4.25e+6;  // same as 4.25e6 or 4250000
var z = 4.25e-6;  // same as 0.00000425

 

Tip: In JavaScript, the largest integer that can be safely represented is 9007199254740991 (253-1), while the smallest safe integer is -9007199254740991 (-(253-1)).

Numbers can be shown in hexadecimal format (base 16), where they start with 0x. Hexadecimal numbers are frequently used to express colors. Here's an illustration:

var x = 0xff;  // same as 255
var y = 0xb4;  // same as 180
var z = 0x00;  // same as 0

 

Note: Integers can be represented as decimal, hexadecimal, and octal notation. Floating-point numbers can be represented as decimal or exponential notation.


Operating on Numbers and Strings

As you've learned in earlier sections, the + operator serves for both adding numbers and joining strings together. Hence, when you perform mathematical operations on both numbers and strings, you might observe some intriguing outcomes. The forthcoming example will demonstrate the effects of combining numbers and strings:

var x = 10;
var y = 20;
var z = "30";

// Adding a number with a number, the result will be sum of numbers
console.log(x + y); // 30

// Adding a string with a string, the result will be string concatenation
console.log(z + z); // '3030'

// Adding a number with a string, the result will be string concatenation
console.log(x + z); // '1030'

// Adding a string with a number, the result will be string concatenation
console.log(z + x); // '3010'

// Adding strings and numbers, the result will be string concatenation
console.log("The result is: " + x + y); // 'The result is: 1020'

// Adding numbers and strings, calculation performed from left to right
console.log(x + y + z); // 'The result is: 3030'

Upon careful observation of the above demonstration, you'll notice that the outcome of the final operation isn't merely a straightforward string concatenation. This is because, when operators with the same level of importance are involved, they're assessed from left to right. Hence, as both variables x and y are numbers, they're first added together, and then the result is combined with the variable z, which is a string. Consequently, the ultimate result is 30 + "30" = "3030".

However, if you engage in other arithmetic operations such as multiplication, division, or subtraction, the outcome will differ. JavaScript automatically converts numeric strings (that is, strings containing numeric values) into numbers for all numeric calculations, as demonstrated in the following example:

var x = 10;
var y = 20;
var z = "30";

// Subtracting a number from a number
console.log(y - x); // 10

// Subtracting a number from a numeric string
console.log(z - x); // 20

// Multiplying a number with a numeric string
console.log(x * z); // 300

// Dividing a number with a numeric string
console.log(z / x); // 3

Additionally, if you attempt to multiply or divide numbers by strings that aren't numeric, JavaScript returns NaN (Not a Number). Furthermore, employing NaN in any mathematical operation yields the result NaN.

var x = 10;
var y = "foo";
var z = NaN;

// Subtracting a number from a non-numeric string
console.log(y - x); // NaN

// Multiplying a number with a non-numeric string
console.log(x * y); // NaN

// Dividing a number with a non-numeric string
console.log(x / y); // NaN

// Adding NaN to a number 
console.log(x + z); // NaN

// Adding NaN to a string 
console.log(y + z); // fooNaN

Representing Infinity

Infinity denotes a number too immense for JavaScript to manage. JavaScript includes special keywords Infinity and -Infinity to denote positive and negative infinity correspondingly. For instance, dividing by 0 results in Infinity, as illustrated below:

var x = 5 / 0;
console.log(x); // Infinity

var y = -5 / 0;
console.log(y); // -Infinity

 

Note: Infinity is a unique value that signifies mathematical Infinity , exceeding any numerical value. When applied to the typeof operator, an Infinity value is classified as a number.


Avoiding Precision Problems

At times, operations involving floating-point numbers yield unforeseen outcomes, as demonstrated below:

var x = 0.1 + 0.2;
console.log(x) // 0.30000000000000004

As observed, the outcome is 0.30000000000000004 instead of the anticipated 0.3. This disparity is termed representation error or roundoff error. It arises because JavaScript, like many other languages, employs binary (base 2) form to internally represent decimal (base 10) numbers. Regrettably, most decimal fractions cannot be precisely represented in binary form, leading to slight discrepancies.

To circumvent this issue, you can utilize a solution similar to the following:

var x = (0.1 * 10 + 0.2 * 10) / 10;
console.log(x) // 0.3

JavaScript typically rounds floating-point numbers to 17 digits, providing adequate precision or accuracy in the majority of scenarios. Moreover, in JavaScript, integers (numbers lacking fractional components or exponential notation) retain accuracy up to 15 digits, as illustrated in the ensuing example:

var x = 999999999999999;
console.log(x); // 999999999999999

var y = 9999999999999999;
console.log(y); // 10000000000000000

Performing Operations on Numbers

JavaScript offers various properties and methods to execute operations on number values. As you've learned in previous sections, in JavaScript, primitive data types can function similarly to objects when accessed using property access notation (i.e., dot notation).

In the forthcoming sections, we'll explore the number methods commonly utilized.

Parsing Integers from Strings

The parseInt() method serves to convert an integer from a string. This method proves especially useful when handling values like CSS units, such as 50px, 12pt, etc., and you wish to extract the numerical value from them.

If the parseInt() method encounters a character that isn't numeric in the specified base, parsing ceases, and it returns the integer value parsed up to that point. If the initial character can't be converted into a number, the method yields NaN (not a number).

Leading and trailing spaces are permissible. Here's an illustration:

console.log(parseInt("3.14"));  // 3
console.log(parseInt("50px"));  // 50
console.log(parseInt("12pt"));  // 12
console.log(parseInt("0xFF", 16));  // 255
console.log(parseInt("20 years"));  // 20
console.log(parseInt("Year 2048"));  // NaN
console.log(parseInt("10 12 2018"));  // 10

 

Note: Although the parseInt() method truncates numbers to integer values, it shouldn't be employed as a replacement for the Math.floor() method.

Likewise, the parseFloat() method enables you to extract floating-point numbers from a string. Functioning similarly to the parseInt() method, parseFloat() retrieves both integers and numbers with decimal points.

console.log(parseFloat("3.14"));  // 3.14
console.log(parseFloat("50px"));  // 50
console.log(parseFloat("1.6em"));  // 1.6
console.log(parseFloat("124.5 lbs"));  // 124.5
console.log(parseFloat("weight 124.5 lbs"));  // NaN
console.log(parseFloat("6.5 acres"));  // 6.5

Converting Numbers to Strings

The toString() method is utilized to transform a number into its string representation. Optionally, this method accepts an integer parameter within the range of 2 through 36, indicating the base for representing numeric values. Here's an illustration:

var x = 10;
var y = x.toString();
console.log(y);  // '10'
console.log(typeof y);  // string
console.log(typeof x);  // number

console.log((12).toString());  // '12'
console.log((15.6).toString());  // '15.6'
console.log((6).toString(2));  // '110'
console.log((255).toString(16));  // 'ff'

Formatting Numbers in Exponential Notation

To format or display a number in exponential notation, you can employ the toExponential() method. Optionally, this method accepts an integer parameter indicating the number of digits after the decimal point. Furthermore, the value returned is a string, not a number. Here's an example:

var x = 67.1234;

console.log(x.toExponential());  // 6.71234e+1
console.log(x.toExponential(6));  // 6.712340e+1
console.log(x.toExponential(4));  // 6.7123e+1
console.log(x.toExponential(2));  // 6.71e+1

 

Note: Exponential notation proves beneficial in portraying numbers of immense or minuscule magnitude. For instance, 62500000000 can be expressed as 625e+8 or 6.25e+10.


Formatting Numbers to Fixed Decimals

When you need to format a number with a fixed number of digits to the right of the decimal point, the toFixed() method comes in handy. The outcome of this method is a string, and it precisely features the specified number of digits after the decimal point. If the digits parameter isn't specified or is omitted, it's interpreted as 0. Here's an example:

var x = 72.635;

console.log(x.toFixed());  // '73' (note rounding, no fractional part)
console.log(x.toFixed(2));  // '72.64' (note rounding)
console.log(x.toFixed(1));  // '72.6'

var y = 6.25e+5;
console.log(y.toFixed(2)); // '625000.00'

var z = 1.58e-4;
console.log(z.toFixed(2));  // '0.00' (since 1.58e-4 is equal to 0.000158)

Formatting Numbers with Precision

If you aim for the most suitable representation of a number, consider employing the toPrecision() method. This method furnishes a string depicting the number to the specified precision.

If the precision encompasses all the digits of the integer part of the number, the number is formatted utilizing fixed-point notation. Alternatively, if the precision is inadequate, exponential notation is utilized. The precision parameter is optional. Here's an example:

var x = 6.235;

console.log(x.toPrecision());  // '6.235'
console.log(x.toPrecision(3));  // '6.24' (note rounding)
console.log(x.toPrecision(2));  // '6.2'
console.log(x.toPrecision(1));  // '6'

var y = 47.63;
console.log(y.toPrecision(2)); // '48' (note rounding, no fractional part)

var z = 1234.5;
console.log(z.toPrecision(2));  // '1.2e+3'

Finding the Largest and Smallest Possible Numbers

The Number object also encompasses several associated properties. The Number.MAX_VALUE and Number.MIN_VALUE properties within the Number object denote the largest and smallest (closest to zero, not the most negative) feasible positive numbers that JavaScript can manage. They are constants, with actual values of 1.7976931348623157e+308 and 5e-324, respectively.

A number that surpasses the range of possible numbers is represented by the constant Number.POSITIVE_INFINITY or Number.NEGATIVE_INFINITY. Here's an example:

var a = Number.MAX_VALUE;
console.log(a); // 1.7976931348623157e+308

var b = Number.MIN_VALUE;
console.log(b); // 5e-324

var x = Number.MAX_VALUE * 2;
console.log(x); // Infinity

var y = -1 * Number.MAX_VALUE * 2;
console.log(y); // -Infinity

Additionally, explore the JavaScript math operations chapter to grasp concepts such as rounding numbers, generating random numbers, determining maximum or minimum values from a set of numbers, and more.