Math.PI
Holds the ratio of a circle's circumference to its diameter, roughly 3.141592653589793.
Math.PI- Added in JavaScript ES1
Return value
numberThe closest double-precision value to π, 3.141592653589793.
Errors
Nothing on read. Assigning to it is silently ignored in sloppy mode and throws a TypeError in strict mode or a module, because the property is non-writable.
Math.PI is a static data property on the Math namespace object, not a method — there are no parentheses and no arguments. It evaluates to the nearest IEEE 754 double to π, which is 3.141592653589793.
When to reach for it
Anywhere an angle in radians meets a value in degrees, and anywhere a circle's size is derived from its radius. JavaScript's trigonometric functions all take radians, so deg * Math.PI / 180 is the conversion you will write most often; rad * 180 / Math.PI goes back the other way.
What trips people up
π is irrational, so Math.PI is an approximation, and every identity built on it inherits that error. Math.sin(Math.PI) is 1.2246467991473532e-16, not 0, and Math.tan(Math.PI / 4) is 0.9999999999999999, not 1. Never compare trigonometric results with ===; compare against a tolerance, or round before display.
The property is non-writable, non-enumerable and non-configurable. Writing Math.PI = 3 does nothing in sloppy mode and throws a TypeError inside a module or a strict-mode function, so shadowing it locally is the only way to "override" it.
Example
When to use it
- Converting user-entered degrees into the radians that Math.sin, Math.cos and Math.atan2 expect
- Computing circumference, arc length or the area of a circle from a radius
- Spacing points evenly around a circle by stepping through (2 * Math.PI) / count
- Normalising an accumulated rotation angle back into the 0 to 2π range
Frequently asked questions
Why does Math.sin(Math.PI) not return 0?
Because Math.PI is a finite approximation of an irrational number, so the argument is slightly off from true π and the sine of that nearby value is 1.2246467991473532e-16. Round the result or compare it against a small tolerance instead of testing for exact zero.
How do I convert degrees to radians in JavaScript?
Multiply by Math.PI and divide by 180: (degrees * Math.PI) / 180. Every Math trigonometric function expects radians, and (radians * 180) / Math.PI converts back.
Can I change the value of Math.PI?
No — the property is non-writable, non-enumerable and non-configurable, so assignment is ignored in sloppy mode and throws a TypeError in strict mode or a module. Object.defineProperty cannot redefine it either.
More examples
Degrees and radians, both directions
90° becomes 1.5707963267948966 and Math.PI / 2 comes back as exactly 90. One radian prints as 57.29577951308232. The round trip through both functions returns 45 unchanged here, but that is luck of the rounding rather than a guarantee for every input.
const toRadians = (deg) => (deg * Math.PI) / 180;
const toDegrees = (rad) => (rad * 180) / Math.PI;
console.log(toRadians(90));
console.log(toDegrees(Math.PI / 2));
console.log(toDegrees(1)); // one radian in degrees
console.log(toDegrees(toRadians(45)));Comparing trigonometric output safely
cos(π/2) prints as 6.123233995736766e-17, so the strict comparison is false. Routing the same two checks through a tolerance of 1e-12 makes both true, which is the pattern to use whenever a test or an assertion touches trigonometry.
console.log(Math.cos(Math.PI / 2)); // not zero
console.log(Math.cos(Math.PI / 2) === 0);
const nearlyEqual = (a, b, eps = 1e-12) => Math.abs(a - b) < eps;
console.log(nearlyEqual(Math.cos(Math.PI / 2), 0));
console.log(nearlyEqual(Math.tan(Math.PI / 4), 1));The property is read-only
The assignment either throws a TypeError or is silently discarded depending on strict mode, and Math.PI still prints 3.141592653589793 afterwards. The descriptor confirms why: writable, enumerable and configurable are all false.
try {
Math.PI = 3;
} catch (err) {
console.log(err.constructor.name);
}
console.log(Math.PI);
const d = Object.getOwnPropertyDescriptor(Math, "PI");
console.log(d.writable, d.enumerable, d.configurable);
Discussion