UNB/ CS/ David Bremner/ teaching/ cs2613/ books/ mdn/ Guide/ Numbers and dates

This chapter introduces the concepts, objects and functions used to work with and perform calculations using numbers and dates in JavaScript. This includes using numbers written in various bases including decimal, binary, and hexadecimal, as well as the use of the global Math object to perform a wide variety of mathematical operations on numbers.

Numbers

In JavaScript, numbers are implemented in double-precision 64-bit binary format IEEE 754 (i.e., a number between ±2^−1022 and ±2^+1023, or about ±10^−308 to ±10^+308, with a numeric precision of 53 bits). Integer values up to ±253 − 1 can be represented exactly.

In addition to being able to represent floating-point numbers, the number type has three symbolic values: +Infinity, -Infinity, and NaN (not-a-number).

See also JavaScript data types and structures for context with other primitive types in JavaScript.

You can use four types of number literals: decimal, binary, octal, and hexadecimal.

Decimal numbers

1234567890
42

Decimal literals can start with a zero (0) followed by another decimal digit, but if all digits after the leading 0 are smaller than 8, the number is interpreted as an octal number. This is considered a legacy syntax, and number literals prefixed with 0, whether interpreted as octal or decimal, cause a syntax error in strict mode — so, use the 0o prefix instead.

0888 // 888 parsed as decimal
0777 // parsed as octal, 511 in decimal

Binary numbers

Binary number syntax uses a leading zero followed by a lowercase or uppercase Latin letter "B" (0b or 0B). If the digits after the 0b are not 0 or 1, the following SyntaxError is thrown: "Missing binary digits after 0b".

0b10000000000000000000000000000000 // 2147483648
0b01111111100000000000000000000000 // 2139095040
0B00000000011111111111111111111111 // 8388607

Octal numbers

The standard syntax for octal numbers is to prefix them with 0o. For example:

0O755 // 493
0o644 // 420

There's also a legacy syntax for octal numbers — by prefixing the octal number with a zero: 0644 === 420 and "\045" === "%". If the digits after the 0 are outside the range 0 through 7, the number will be interpreted as a decimal number.

const n = 0755; // 493
const m = 0644; // 420

Strict mode forbids this octal syntax.

Hexadecimal numbers

Hexadecimal number syntax uses a leading zero followed by a lowercase or uppercase Latin letter "X" (0x or 0X). If the digits after 0x are outside the range (0123456789ABCDEF), the following SyntaxError is thrown: "Identifier starts immediately after numeric literal".

0xFFFFFFFFFFFFFFFFF // 295147905179352830000
0x123456789ABCDEF   // 81985529216486900
0XA                 // 10

Exponentiation

0e-5   // 0
0e+5   // 0
5e1    // 50
175e-2 // 1.75
1e3    // 1000
1e-3   // 0.001
1E3    // 1000

Number object

The built-in Number object has properties for numerical constants, such as maximum value, not-a-number, and infinity. You cannot change the values of these properties and you use them as follows:

const biggestNum = Number.MAX_VALUE;
const smallestNum = Number.MIN_VALUE;
const infiniteNum = Number.POSITIVE_INFINITY;
const negInfiniteNum = Number.NEGATIVE_INFINITY;
const notANum = Number.NaN;

You always refer to a property of the predefined Number object as shown above, and not as a property of a Number object you create yourself.

The following table summarizes the Number object's properties.

Property Description
Number.MAX_VALUE The largest positive representable number (1.7976931348623157e+308)
Number.MIN_VALUE The smallest positive representable number (5e-324)
Number.NaN Special "not a number" value
Number.NEGATIVE_INFINITY Special negative infinite value; returned on overflow
Number.POSITIVE_INFINITY Special positive infinite value; returned on overflow
Number.EPSILON Difference between 1 and the smallest value greater than 1 that can be represented as a Number (2.220446049250313e-16)
Number.MIN_SAFE_INTEGER Minimum safe integer in JavaScript (−253 + 1, or −9007199254740991)
Number.MAX_SAFE_INTEGER Maximum safe integer in JavaScript (+253 − 1, or +9007199254740991)
Method Description
Number.parseFloat Parses a string argument and returns a floating point number. Same as the global parseFloat() function.
Number.parseInt Parses a string argument and returns an integer of the specified radix or base. Same as the global parseInt() function.
Number.isFinite Determines whether the passed value is a finite number.
Number.isInteger Determines whether the passed value is an integer.
Number.isNaN Determines whether the passed value is NaN. More robust version of the original global isNaN().
Number.isSafeInteger Determines whether the provided value is a number that is a safe integer.

The Number prototype provides methods for retrieving information from Number objects in various formats. The following table summarizes the methods of Number.prototype.

Method Description
toExponential() Returns a string representing the number in exponential notation.
toFixed() Returns a string representing the number in fixed-point notation.
toPrecision() Returns a string representing the number to a specified precision in fixed-point notation.

Math object

The built-in Math object has properties and methods for mathematical constants and functions. For example, the Math object's PI property has the value of pi (3.141…), which you would use in an application as

Math.PI;

Similarly, standard mathematical functions are methods of Math. These include trigonometric, logarithmic, exponential, and other functions. For example, if you want to use the trigonometric function sine, you would write

Math.sin(1.56);

Note that all trigonometric methods of Math take arguments in radians.

The following table summarizes the Math object's methods.

Methods of Math
Method Description
[abs()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.abs) Absolute value
[sin()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.sin), [cos()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.cos), [tan()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.tan) Standard trigonometric functions; with the argument in radians.
[asin()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.asin), [acos()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.acos), [atan()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.atan), [atan2()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.atan2) Inverse trigonometric functions; return values in radians.
[sinh()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.sinh), [cosh()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.cosh), [tanh()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.tanh) Hyperbolic functions; argument in hyperbolic angle.
[asinh()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.asinh), [acosh()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.acosh), [atanh()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.atanh) Inverse hyperbolic functions; return values in hyperbolic angle.

[pow()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.pow), [exp()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.exp), [expm1()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.expm1), [log()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.log), [log10()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.log10), [log1p()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.log1p), [log2()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.log2)

Exponential and logarithmic functions.
[floor()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.floor), [ceil()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.ceil) Returns the largest/smallest integer less/greater than or equal to an argument.
[min()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.min), [max()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.max) Returns the minimum or maximum (respectively) value of a comma separated list of numbers as arguments.
[random()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.random) Returns a random number between 0 and 1.
[round()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.round), [fround()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.fround), [trunc()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.trunc), Rounding and truncation functions.
[sqrt()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.sqrt), [cbrt()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.cbrt), [hypot()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.hypot) Square root, cube root, Square root of the sum of square arguments.
[sign()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.sign) The sign of a number, indicating whether the number is positive, negative or zero.
[clz32()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.clz32),
[imul()](/~bremner/teaching/cs2613/books/mdn/Reference/Global_Objects/Math.imul)
Number of leading zero bits in the 32-bit binary representation.
The result of the C-like 32-bit multiplication of the two arguments.

Unlike many other objects, you never create a Math object of your own. You always use the built-in Math object.

BigInts

One shortcoming of number values is they only have 64 bits. In practice, due to using IEEE 754 encoding, they cannot represent any integer larger than Number.MAX_SAFE_INTEGER (which is 253 - 1) accurately. To solve the need of encoding binary data and to interoperate with other languages that offer wide integers like i64 (64-bit integers) and i128 (128-bit integers), JavaScript also offers another data type to represent arbitrarily large integers: BigInt.

A BigInt can be defined as an integer literal suffixed by n:

const b1 = 123n;
// Can be arbitrarily large.
const b2 = -1234567890987654321n;

BigInts can also be constructed from number values or string values using the BigInt constructor.

const b1 = BigInt(123);
// Using a string prevents loss of precision, since long number
// literals don't represent what they seem like.
const b2 = BigInt("-1234567890987654321");

Conceptually, a BigInt is just an arbitrarily long sequence of bits which encodes an integer. You can safely do any arithmetic operations without losing precision or over-/underflowing.

const integer = 12 ** 34; // 4.9222352429520264e+36; only has limited precision
const bigint = 12n ** 34n; // 4922235242952026704037113243122008064n

Compared to numbers, BigInt values yield higher precision when representing large integers; however, they cannot represent floating-point numbers. For example, division would round to zero:

const bigintDiv = 5n / 2n; // 2n, because there's no 2.5 in BigInt

Math functions cannot be used on BigInt values. There is an open proposal to overload certain Math functions like Math.max() to allow BigInt values.

Choosing between BigInt and number depends on your use-case and your input's range. The precision of numbers should be able to accommodate most day-to-day tasks already, and BigInts are most suitable for handling binary data.

Read more about what you can do with BigInt values in the Expressions and Operators section, or the BigInt reference.

Date object

JavaScript does not have a date data type. However, you can use the Date object and its methods to work with dates and times in your applications. The Date object has a large number of methods for setting, getting, and manipulating dates. It does not have any properties.

JavaScript handles dates similarly to Java. The two languages have many of the same date methods, and both languages store dates as the number of milliseconds since midnight at the beginning of January 1, 1970, UTC, with a Unix Timestamp being the number of seconds since the same instant. The instant at the midnight at the beginning of January 1, 1970, UTC is called the epoch.

The Date object range is -100,000,000 days to 100,000,000 days relative to the epoch.

To create a Date object:

const dateObjectName = new Date([parameters]);

where dateObjectName is the name of the Date object being created; it can be a new object or a property of an existing object.

Calling Date without the new keyword returns a string representing the current date and time.

The parameters in the preceding syntax can be any of the following:

Methods of the Date object

The Date object methods for handling dates and times fall into these broad categories:

With the "get" and "set" methods you can get and set seconds, minutes, hours, day of the month, day of the week, months, and years separately. There is a getDay method that returns the day of the week, but no corresponding setDay method, because the day of the week is set automatically. These methods use integers to represent these values as follows:

For example, suppose you define the following date:

const xmas95 = new Date("1995-12-25");

Then xmas95.getMonth() returns 11, and xmas95.getFullYear() returns 1995.

The getTime and setTime methods are useful for comparing dates. The getTime method returns the number of milliseconds since the epoch for a Date object.

For example, the following code displays the number of days left in the current year:

const today = new Date();
const endYear = new Date(1995, 11, 31, 23, 59, 59, 999); // Set day and month
endYear.setFullYear(today.getFullYear()); // Set year to this year
const msPerDay = 24 * 60 * 60 * 1000; // Number of milliseconds per day
let daysLeft = (endYear.getTime() - today.getTime()) / msPerDay;
daysLeft = Math.round(daysLeft); // Returns days left in the year

This example creates a Date object named today that contains today's date. It then creates a Date object named endYear and sets the year to the current year. Then, using the number of milliseconds per day, it computes the number of days between today and endYear, using getTime and rounding to a whole number of days.

The parse method is useful for assigning values from date strings to existing Date objects. For example, the following code uses parse and setTime to assign a date value to the ipoDate object:

const ipoDate = new Date();
ipoDate.setTime(Date.parse("Aug 9, 1995"));

Example

In the following example, the function JSClock() returns the time in the format of a digital clock.

function JSClock() {
  const time = new Date();
  const hour = time.getHours();
  const minute = time.getMinutes();
  const second = time.getSeconds();
  let temp = String(hour % 12);
  if (temp === "0") {
    temp = "12";
  }
  temp += (minute < 10 ? ":0" : ":") + minute;
  temp += (second < 10 ? ":0" : ":") + second;
  temp += hour >= 12 ? " P.M." : " A.M.";
  return temp;
}

The JSClock function first creates a new Date object called time; since no arguments are given, time is created with the current date and time. Then calls to the getHours, getMinutes, and getSeconds methods assign the value of the current hour, minute, and second to hour, minute, and second.

The following statements build a string value based on the time. The first statement creates a variable temp. Its value is hour % 12, which is hour in the 12-hour system. Then, if the hour is 0, it gets re-assigned to 12, so that midnights and noons are displayed as 12:00 instead of 0:00.

The next statement appends a minute value to temp. If the value of minute is less than 10, the conditional expression adds a string with a preceding zero; otherwise it adds a string with a demarcating colon. Then a statement appends a seconds value to temp in the same way.

Finally, a conditional expression appends "P.M." to temp if hour is 12 or greater; otherwise, it appends "A.M." to temp.