From 99f31f95711d5e1bdf54e9f6dbd35021e4a5688a Mon Sep 17 00:00:00 2001 From: sarthakgupta1907-cell Date: Sat, 7 Nov 2026 18:13:30 +0530 Subject: [PATCH] feat: add Pi approximation using Leibniz formula --- Maths/PiApproximation.js | 22 ++++++++++++++ Maths/test/PiApproximation.test.js | 46 ++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 Maths/PiApproximation.js create mode 100644 Maths/test/PiApproximation.test.js diff --git a/Maths/PiApproximation.js b/Maths/PiApproximation.js new file mode 100644 index 0000000000..6aab9ac416 --- /dev/null +++ b/Maths/PiApproximation.js @@ -0,0 +1,22 @@ +/** + * @function leibnizPi + * @description Approximates Pi using the Leibniz formula: + * π/4 = 1 - 1/3 + 1/5 - 1/7 + 1/9 - ... + * @param {number} terms - Number of terms to use in approximation + * @returns {number} - Approximation of Pi + * @see https://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80 + * @example leibnizPi(1000) => ~3.1405926... + * @example leibnizPi(10000) => ~3.1414926... + */ +const leibnizPi = (terms) => { + if (!Number.isInteger(terms) || terms < 1) { + throw new TypeError('Input must be a positive integer') + } + let sum = 0 + for (let i = 0; i < terms; i++) { + sum += (-1) ** i / (2 * i + 1) + } + return 4 * sum +} + +export { leibnizPi } diff --git a/Maths/test/PiApproximation.test.js b/Maths/test/PiApproximation.test.js new file mode 100644 index 0000000000..c7052adde8 --- /dev/null +++ b/Maths/test/PiApproximation.test.js @@ -0,0 +1,46 @@ +import { leibnizPi } from '../PiApproximation.js' + +describe('leibnizPi', () => { + test('leibnizPi(1) returns 4', () => { + expect(leibnizPi(1)).toBe(4) + }) + + test('leibnizPi(2) returns 2.666...', () => { + expect(leibnizPi(2)).toBeCloseTo(2.667, 2) + }) + + test('leibnizPi(100) approximates pi', () => { + expect(leibnizPi(100)).toBeCloseTo(3.13, 1) + }) + + test('leibnizPi(1000) approximates pi more closely', () => { + expect(leibnizPi(1000)).toBeCloseTo(3.14, 2) + }) + + test('leibnizPi(10000) approximates pi even more closely', () => { + expect(leibnizPi(10000)).toBeCloseTo(3.1415, 3) + }) + + test('more terms give better approximation', () => { + const pi = Math.PI + expect(Math.abs(leibnizPi(10000) - pi)).toBeLessThan( + Math.abs(leibnizPi(100) - pi) + ) + }) + + test('throws TypeError for zero', () => { + expect(() => leibnizPi(0)).toThrow(TypeError) + }) + + test('throws TypeError for negative input', () => { + expect(() => leibnizPi(-100)).toThrow(TypeError) + }) + + test('throws TypeError for float input', () => { + expect(() => leibnizPi(100.5)).toThrow(TypeError) + }) + + test('throws TypeError for string input', () => { + expect(() => leibnizPi('100')).toThrow(TypeError) + }) +})