JavaScript Math
Math 对象是 JavaScript 的内置对象,提供了各种数学常数和数学函数。它是一个静态对象,所有属性和方法都直接通过 Math 对象访问,而不需要创建实例。在本章节中,我们将深入学习 JavaScript 中的 Math 对象及其各种数学方法。
什么是 Math 对象
Math 对象为数学常数和函数提供了属性和方法。与其他全局对象不同,Math 不是一个构造函数,不能使用 new Math() 创建实例。
Math 对象的特点
- 静态对象:所有属性和方法都是静态的
- 不可实例化:不能创建 Math 的实例
- 内置对象:JavaScript 环境自带
- 跨平台:在所有 JavaScript 环境中行为一致
Math 常数属性
javascript
// 基本数学常数
console.log(Math.E); // 2.718281828459045 (自然对数的底数)
console.log(Math.PI); // 3.141592653589793 (圆周率)
console.log(Math.SQRT2); // 1.4142135623730951 (2的平方根)
console.log(Math.SQRT1_2); // 0.7071067811865476 (1/2的平方根)
console.log(Math.LN2); // 0.6931471805599453 (2的自然对数)
console.log(Math.LN10); // 2.302585092994046 (10的自然对数)
console.log(Math.LOG2E); // 1.4426950408889634 (以2为底E的对数)
console.log(Math.LOG10E); // 0.4342944819032518 (以10为底E的对数)
// 使用示例
const circleArea = Math.PI * Math.pow(5, 2); // 半径为5的圆面积
console.log(circleArea); // 78.53981633974483
const hypotenuse = Math.sqrt(Math.pow(3, 2) + Math.pow(4, 2)); // 直角三角形斜边
console.log(hypotenuse); // 5基本数学函数
绝对值和符号函数
javascript
// Math.abs() - 绝对值
console.log(Math.abs(-5)); // 5
console.log(Math.abs(5)); // 5
console.log(Math.abs(0)); // 0
console.log(Math.abs(-3.14)); // 3.14
// Math.sign() - 符号函数 (ES6)
console.log(Math.sign(5)); // 1 (正数)
console.log(Math.sign(-5)); // -1 (负数)
console.log(Math.sign(0)); // 0 (零)
console.log(Math.sign(-0)); // -0 (负零)
console.log(Math.sign(NaN)); // NaN取整函数
javascript
const num = 3.7;
// Math.floor() - 向下取整
console.log(Math.floor(num)); // 3
console.log(Math.floor(-3.7)); // -4
// Math.ceil() - 向上取整
console.log(Math.ceil(num)); // 4
console.log(Math.ceil(-3.7)); // -3
// Math.round() - 四舍五入
console.log(Math.round(num)); // 4
console.log(Math.round(3.4)); // 3
console.log(Math.round(3.5)); // 4
console.log(Math.round(-3.5)); // -3 (注意:-3.5 四舍五入为 -3)
// Math.trunc() - 截断小数部分 (ES6)
console.log(Math.trunc(num)); // 3
console.log(Math.trunc(-3.7)); // -3
console.log(Math.trunc(3.9)); // 3幂和根函数
javascript
// Math.pow() - 幂运算
console.log(Math.pow(2, 3)); // 8 (2的3次方)
console.log(Math.pow(4, 0.5)); // 2 (4的平方根)
console.log(Math.pow(10, 2)); // 100 (10的平方)
// Math.sqrt() - 平方根
console.log(Math.sqrt(16)); // 4
console.log(Math.sqrt(2)); // 1.4142135623730951
console.log(Math.sqrt(0)); // 0
console.log(Math.sqrt(-1)); // NaN
// Math.cbrt() - 立方根 (ES6)
console.log(Math.cbrt(27)); // 3
console.log(Math.cbrt(-8)); // -2
console.log(Math.cbrt(0)); // 0
// Math.hypot() - 平方和的平方根 (ES6)
console.log(Math.hypot(3, 4)); // 5 (3² + 4² = 25, √25 = 5)
console.log(Math.hypot(1, 2, 3)); // 3.7416573867739413对数和指数函数
指数函数
javascript
// Math.exp() - e的x次方
console.log(Math.exp(1)); // 2.718281828459045 (e¹)
console.log(Math.exp(0)); // 1 (e⁰)
console.log(Math.exp(2)); // 7.38905609893065 (e²)
// Math.expm1() - e的x次方减1 (ES6)
console.log(Math.expm1(1)); // 1.718281828459045 (e¹ - 1)
console.log(Math.expm1(0)); // 0 (e⁰ - 1)对数函数
javascript
// Math.log() - 自然对数 (以e为底)
console.log(Math.log(Math.E)); // 1
console.log(Math.log(1)); // 0
console.log(Math.log(10)); // 2.302585092994046
// Math.log10() - 以10为底的对数 (ES6)
console.log(Math.log10(10)); // 1
console.log(Math.log10(100)); // 2
console.log(Math.log10(1)); // 0
// Math.log2() - 以2为底的对数 (ES6)
console.log(Math.log2(2)); // 1
console.log(Math.log2(8)); // 3
console.log(Math.log2(1)); // 0
// Math.log1p() - ln(1+x) (ES6)
console.log(Math.log1p(0)); // 0
console.log(Math.log1p(Math.E - 1)); // 1三角函数
基本三角函数
javascript
// 角度转弧度的辅助函数
function toRadians(degrees) {
return degrees * (Math.PI / 180);
}
function toDegrees(radians) {
return radians * (180 / Math.PI);
}
// Math.sin() - 正弦函数
console.log(Math.sin(0)); // 0
console.log(Math.sin(Math.PI / 2)); // 1
console.log(Math.sin(toRadians(30))); // 0.49999999999999994 ≈ 0.5
// Math.cos() - 余弦函数
console.log(Math.cos(0)); // 1
console.log(Math.cos(Math.PI)); // -1
console.log(Math.cos(toRadians(60))); // 0.5000000000000001 ≈ 0.5
// Math.tan() - 正切函数
console.log(Math.tan(0)); // 0
console.log(Math.tan(toRadians(45))); // 0.9999999999999999 ≈ 1
// 反三角函数
console.log(Math.asin(1)); // 1.5707963267948966 (π/2)
console.log(Math.acos(0)); // 1.5707963267948966 (π/2)
console.log(Math.atan(1)); // 0.7853981633974483 (π/4)
console.log(Math.atan2(1, 1)); // 0.7853981633974483 (π/4)双曲函数 (ES6)
javascript
// 双曲正弦
console.log(Math.sinh(0)); // 0
console.log(Math.sinh(1)); // 1.1752011936438014
// 双曲余弦
console.log(Math.cosh(0)); // 1
console.log(Math.cosh(1)); // 1.5430806348152437
// 双曲正切
console.log(Math.tanh(0)); // 0
console.log(Math.tanh(1)); // 0.7615941559557649
// 反双曲函数
console.log(Math.asinh(0)); // 0
console.log(Math.acosh(1)); // 0
console.log(Math.atanh(0)); // 0最值函数
javascript
// Math.max() - 最大值
console.log(Math.max(1, 2, 3, 4, 5)); // 5
console.log(Math.max(-1, -2, -3)); // -1
console.log(Math.max()); // -Infinity
// Math.min() - 最小值
console.log(Math.min(1, 2, 3, 4, 5)); // 1
console.log(Math.min(-1, -2, -3)); // -3
console.log(Math.min()); // Infinity
// 处理数组
const numbers = [1, 5, 3, 9, 2];
console.log(Math.max(...numbers)); // 9
console.log(Math.min(...numbers)); // 1
// 使用 apply (ES5 方式)
console.log(Math.max.apply(null, numbers)); // 9
console.log(Math.min.apply(null, numbers)); // 1随机数函数
javascript
// Math.random() - 生成 0 到 1 之间的随机数
console.log(Math.random()); // 例如: 0.8441828566137701
// 生成指定范围的随机整数
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
console.log(randomInt(1, 10)); // 1到10之间的随机整数
console.log(randomInt(0, 100)); // 0到100之间的随机整数
// 生成指定范围的随机浮点数
function randomFloat(min, max, decimals = 2) {
const factor = Math.pow(10, decimals);
return Math.round((Math.random() * (max - min) + min) * factor) / factor;
}
console.log(randomFloat(1, 10)); // 1到10之间的随机浮点数,保留2位小数
console.log(randomFloat(0, 1, 4)); // 0到1之间的随机浮点数,保留4位小数
// 随机布尔值
function randomBoolean() {
return Math.random() >= 0.5;
}
console.log(randomBoolean()); // true 或 false
// 随机数组元素
function randomElement(array) {
const randomIndex = Math.floor(Math.random() * array.length);
return array[randomIndex];
}
const fruits = ["苹果", "香蕉", "橙子", "葡萄"];
console.log(randomElement(fruits)); // 随机水果Math 工具函数
数学工具类
javascript
class MathUtils {
// 角度和弧度转换
static degreesToRadians(degrees) {
return degrees * (Math.PI / 180);
}
static radiansToDegrees(radians) {
return radians * (180 / Math.PI);
}
// 计算两点间距离
static distance(x1, y1, x2, y2) {
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
}
// 计算点到直线的距离
static pointToLineDistance(px, py, x1, y1, x2, y2) {
const A = px - x1;
const B = py - y1;
const C = x2 - x1;
const D = y2 - y1;
const dot = A * C + B * D;
const lenSq = C * C + D * D;
let param = -1;
if (lenSq !== 0) {
param = dot / lenSq;
}
let xx, yy;
if (param < 0) {
xx = x1;
yy = y1;
} else if (param > 1) {
xx = x2;
yy = y2;
} else {
xx = x1 + param * C;
yy = y1 + param * D;
}
const dx = px - xx;
const dy = py - yy;
return Math.sqrt(dx * dx + dy * dy);
}
// 判断是否为质数
static 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;
}
// 计算阶乘
static factorial(n) {
if (n < 0) return NaN;
if (n === 0 || n === 1) return 1;
let result = 1;
for (let i = 2; i <= n; i++) {
result *= i;
}
return result;
}
// 计算最大公约数
static gcd(a, b) {
a = Math.abs(a);
b = Math.abs(b);
while (b !== 0) {
const temp = b;
b = a % b;
a = temp;
}
return a;
}
// 计算最小公倍数
static lcm(a, b) {
return Math.abs(a * b) / this.gcd(a, b);
}
// 线性插值
static lerp(start, end, t) {
return start + (end - start) * t;
}
// 克拉默法则解二元一次方程组
static solveLinearEquations(a1, b1, c1, a2, b2, c2) {
const det = a1 * b2 - a2 * b1;
if (det === 0) {
throw new Error("方程组无唯一解");
}
const x = (c1 * b2 - c2 * b1) / det;
const y = (a1 * c2 - a2 * c1) / det;
return { x, y };
}
// 计算圆的面积
static circleArea(radius) {
return Math.PI * radius * radius;
}
// 计算圆的周长
static circleCircumference(radius) {
return 2 * Math.PI * radius;
}
// 计算球体体积
static sphereVolume(radius) {
return (4 / 3) * Math.PI * Math.pow(radius, 3);
}
// 计算球体表面积
static sphereSurfaceArea(radius) {
return 4 * Math.PI * radius * radius;
}
// 计算三角形面积 (海伦公式)
static triangleArea(a, b, c) {
const s = (a + b + c) / 2; // 半周长
return Math.sqrt(s * (s - a) * (s - b) * (s - c));
}
// 计算两点间角度
static angleBetweenPoints(x1, y1, x2, y2) {
return Math.atan2(y2 - y1, x2 - x1);
}
// 限制数值范围
static clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
}
// 映射数值范围
static map(value, inMin, inMax, outMin, outMax) {
return ((value - inMin) / (inMax - inMin)) * (outMax - outMin) + outMin;
}
// 计算百分比
static percentage(value, total) {
return (value / total) * 100;
}
// 计算折扣价格
static discountPrice(originalPrice, discountPercent) {
return originalPrice * (1 - discountPercent / 100);
}
}
// 使用示例
console.log(MathUtils.degreesToRadians(180)); // 3.141592653589793 (π)
console.log(MathUtils.radiansToDegrees(Math.PI)); // 180
console.log(MathUtils.distance(0, 0, 3, 4)); // 5
console.log(MathUtils.pointToLineDistance(1, 1, 0, 0, 2, 0)); // 1
console.log(MathUtils.isPrime(17)); // true
console.log(MathUtils.isPrime(18)); // false
console.log(MathUtils.factorial(5)); // 120
console.log(MathUtils.gcd(12, 18)); // 6
console.log(MathUtils.lcm(12, 18)); // 36
console.log(MathUtils.lerp(0, 100, 0.5)); // 50
console.log(MathUtils.solveLinearEquations(1, 2, 5, 3, 4, 11)); // { x: 1, y: 2 }
console.log(MathUtils.circleArea(5)); // 78.53981633974483
console.log(MathUtils.circleCircumference(5)); // 31.41592653589793
console.log(MathUtils.sphereVolume(5)); // 523.5987755982989
console.log(MathUtils.sphereSurfaceArea(5)); // 314.1592653589793
console.log(MathUtils.triangleArea(3, 4, 5)); // 6
console.log(MathUtils.angleBetweenPoints(0, 0, 1, 1)); // 0.7853981633974483
console.log(MathUtils.clamp(15, 1, 10)); // 10
console.log(MathUtils.map(5, 0, 10, 0, 100)); // 50
console.log(MathUtils.percentage(25, 100)); // 25
console.log(MathUtils.discountPrice(100, 20)); // 80数值处理和精度
精确计算工具
javascript
class PrecisionMath {
// 精确加法
static add(a, b, precision = 10) {
return parseFloat((a + b).toFixed(precision));
}
// 精确减法
static subtract(a, b, precision = 10) {
return parseFloat((a - b).toFixed(precision));
}
// 精确乘法
static multiply(a, b, precision = 10) {
return parseFloat((a * b).toFixed(precision));
}
// 精确除法
static divide(a, b, precision = 10) {
if (b === 0) {
throw new Error("除数不能为零");
}
return parseFloat((a / b).toFixed(precision));
}
// 精确幂运算
static power(base, exponent, precision = 10) {
return parseFloat(Math.pow(base, exponent).toFixed(precision));
}
// 精确平方根
static sqrt(num, precision = 10) {
if (num < 0) {
throw new Error("负数不能开平方根");
}
return parseFloat(Math.sqrt(num).toFixed(precision));
}
// 精确对数
static log(num, base = Math.E, precision = 10) {
if (num <= 0) {
throw new Error("对数的真数必须大于0");
}
if (base <= 0 || base === 1) {
throw new Error("对数的底数必须大于0且不等于1");
}
if (base === Math.E) {
return parseFloat(Math.log(num).toFixed(precision));
} else if (base === 10) {
return parseFloat(Math.log10(num).toFixed(precision));
} else if (base === 2) {
return parseFloat(Math.log2(num).toFixed(precision));
} else {
// 换底公式: log_a(b) = ln(b) / ln(a)
return parseFloat((Math.log(num) / Math.log(base)).toFixed(precision));
}
}
// 精确三角函数
static sin(angle, unit = "radians", precision = 10) {
const radians = unit === "degrees" ? angle * (Math.PI / 180) : angle;
return parseFloat(Math.sin(radians).toFixed(precision));
}
static cos(angle, unit = "radians", precision = 10) {
const radians = unit === "degrees" ? angle * (Math.PI / 180) : angle;
return parseFloat(Math.cos(radians).toFixed(precision));
}
static tan(angle, unit = "radians", precision = 10) {
const radians = unit === "degrees" ? angle * (Math.PI / 180) : angle;
return parseFloat(Math.tan(radians).toFixed(precision));
}
// 精确反三角函数
static asin(value, unit = "radians", precision = 10) {
const radians = Math.asin(value);
return unit === "degrees"
? parseFloat((radians * (180 / Math.PI)).toFixed(precision))
: parseFloat(radians.toFixed(precision));
}
static acos(value, unit = "radians", precision = 10) {
const radians = Math.acos(value);
return unit === "degrees"
? parseFloat((radians * (180 / Math.PI)).toFixed(precision))
: parseFloat(radians.toFixed(precision));
}
static atan(value, unit = "radians", precision = 10) {
const radians = Math.atan(value);
return unit === "degrees"
? parseFloat((radians * (180 / Math.PI)).toFixed(precision))
: parseFloat(radians.toFixed(precision));
}
// 数值比较(考虑精度)
static isEqual(a, b, epsilon = Number.EPSILON) {
return Math.abs(a - b) < epsilon;
}
// 四舍五入到指定小数位
static round(value, decimals = 0) {
const factor = Math.pow(10, decimals);
return Math.round(value * factor) / factor;
}
// 向下取整到指定小数位
static floor(value, decimals = 0) {
const factor = Math.pow(10, decimals);
return Math.floor(value * factor) / factor;
}
// 向上取整到指定小数位
static ceil(value, decimals = 0) {
const factor = Math.pow(10, decimals);
return Math.ceil(value * factor) / factor;
}
}
// 使用示例
console.log(PrecisionMath.add(0.1, 0.2)); // 0.3
console.log(PrecisionMath.subtract(0.3, 0.1)); // 0.2
console.log(PrecisionMath.multiply(0.1, 0.2)); // 0.02
console.log(PrecisionMath.divide(0.3, 0.1)); // 3
console.log(PrecisionMath.power(2, 3)); // 8
console.log(PrecisionMath.sqrt(16)); // 4
console.log(PrecisionMath.log(10, 10)); // 1
console.log(PrecisionMath.log(Math.E)); // 1
console.log(PrecisionMath.sin(30, "degrees")); // 0.5
console.log(PrecisionMath.cos(60, "degrees")); // 0.5
console.log(PrecisionMath.tan(45, "degrees")); // 1
console.log(PrecisionMath.asin(0.5, "degrees")); // 30
console.log(PrecisionMath.acos(0.5, "degrees")); // 60
console.log(PrecisionMath.atan(1, "degrees")); // 45
console.log(PrecisionMath.isEqual(0.1 + 0.2, 0.3)); // true
console.log(PrecisionMath.round(3.14159, 2)); // 3.14
console.log(PrecisionMath.floor(3.14159, 2)); // 3.14
console.log(PrecisionMath.ceil(3.14159, 2)); // 3.15实际应用示例
1. 几何计算工具
javascript
class GeometryCalculator {
// 计算两点间距离
static distance(x1, y1, x2, y2) {
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
}
// 计算点到直线的距离
static pointToLineDistance(px, py, x1, y1, x2, y2) {
const A = px - x1;
const B = py - y1;
const C = x2 - x1;
const D = y2 - y1;
const dot = A * C + B * D;
const lenSq = C * C + D * D;
let param = -1;
if (lenSq !== 0) {
param = dot / lenSq;
}
let xx, yy;
if (param < 0) {
xx = x1;
yy = y1;
} else if (param > 1) {
xx = x2;
yy = y2;
} else {
xx = x1 + param * C;
yy = y1 + param * D;
}
const dx = px - xx;
const dy = py - yy;
return Math.sqrt(dx * dx + dy * dy);
}
// 计算三角形面积
static triangleAreaByPoints(x1, y1, x2, y2, x3, y3) {
return Math.abs((x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)) / 2);
}
// 使用海伦公式计算三角形面积
static triangleAreaBySides(a, b, c) {
// 检查是否能构成三角形
if (a + b <= c || a + c <= b || b + c <= a) {
throw new Error("这三条边不能构成三角形");
}
const s = (a + b + c) / 2; // 半周长
return Math.sqrt(s * (s - a) * (s - b) * (s - c));
}
// 计算圆的面积
static circleArea(radius) {
return Math.PI * radius * radius;
}
// 计算圆的周长
static circleCircumference(radius) {
return 2 * Math.PI * radius;
}
// 计算扇形面积
static sectorArea(radius, angleInDegrees) {
const angleInRadians = angleInDegrees * (Math.PI / 180);
return 0.5 * radius * radius * angleInRadians;
}
// 计算椭圆面积
static ellipseArea(a, b) {
return Math.PI * a * b;
}
// 计算矩形面积
static rectangleArea(width, height) {
return width * height;
}
// 计算矩形周长
static rectanglePerimeter(width, height) {
return 2 * (width + height);
}
// 计算平行四边形面积
static parallelogramArea(base, height) {
return base * height;
}
// 计算梯形面积
static trapezoidArea(top, bottom, height) {
return 0.5 * (top + bottom) * height;
}
// 计算球体体积
static sphereVolume(radius) {
return (4 / 3) * Math.PI * Math.pow(radius, 3);
}
// 计算球体表面积
static sphereSurfaceArea(radius) {
return 4 * Math.PI * radius * radius;
}
// 计算圆柱体体积
static cylinderVolume(radius, height) {
return Math.PI * radius * radius * height;
}
// 计算圆柱体表面积
static cylinderSurfaceArea(radius, height) {
return 2 * Math.PI * radius * (radius + height);
}
// 计算圆锥体体积
static coneVolume(radius, height) {
return (1 / 3) * Math.PI * radius * radius * height;
}
// 计算两点间角度
static angleBetweenPoints(x1, y1, x2, y2) {
return Math.atan2(y2 - y1, x2 - x1) * (180 / Math.PI);
}
// 判断点是否在矩形内
static isPointInRectangle(px, py, x, y, width, height) {
return px >= x && px <= x + width && py >= y && py <= y + height;
}
// 判断点是否在圆内
static isPointInCircle(px, py, cx, cy, radius) {
return Math.sqrt(Math.pow(px - cx, 2) + Math.pow(py - cy, 2)) <= radius;
}
}
// 使用示例
console.log(GeometryCalculator.distance(0, 0, 3, 4)); // 5
console.log(GeometryCalculator.pointToLineDistance(1, 1, 0, 0, 2, 0)); // 1
console.log(GeometryCalculator.triangleAreaByPoints(0, 0, 4, 0, 0, 3)); // 6
console.log(GeometryCalculator.triangleAreaBySides(3, 4, 5)); // 6
console.log(GeometryCalculator.circleArea(5)); // 78.53981633974483
console.log(GeometryCalculator.circleCircumference(5)); // 31.41592653589793
console.log(GeometryCalculator.sectorArea(5, 90)); // 19.634954084936208
console.log(GeometryCalculator.rectangleArea(4, 5)); // 20
console.log(GeometryCalculator.rectanglePerimeter(4, 5)); // 18
console.log(GeometryCalculator.sphereVolume(5)); // 523.5987755982989
console.log(GeometryCalculator.sphereSurfaceArea(5)); // 314.1592653589793
console.log(GeometryCalculator.angleBetweenPoints(0, 0, 1, 1)); // 45
console.log(GeometryCalculator.isPointInRectangle(2, 2, 0, 0, 5, 5)); // true
console.log(GeometryCalculator.isPointInCircle(2, 2, 0, 0, 5)); // true2. 金融计算工具
javascript
class FinancialCalculator {
// 计算复利
static compoundInterest(principal, rate, time, compoundFrequency = 1) {
return principal * Math.pow(1 + (rate / 100) / compoundFrequency, compoundFrequency * time);
}
// 计算简单利息
static simpleInterest(principal, rate, time) {
return principal * (rate / 100) * time;
}
// 计算贷款月供
static loanPayment(principal, annualRate, months) {
const monthlyRate = (annualRate / 100) / 12;
if (monthlyRate === 0) {
return principal / months;
}
return (principal * monthlyRate * Math.pow(1 + monthlyRate, months)) /
(Math.pow(1 + monthlyRate, months) - 1);
}
// 计算贷款总利息
static loanTotalInterest(principal, annualRate, months) {
const monthlyPayment = this.loanPayment(principal, annualRate, months);
return monthlyPayment * months - principal;
}
// 计算投资回报率 (ROI)
static roi(investment, returnAmount) {
return ((returnAmount - investment) / investment) * 100;
}
// 计算年化收益率
static annualizedReturn(initialValue, finalValue, years) {
return (Math.pow(finalValue / initialValue, 1 / years) - 1) * 100;
}
// 计算现值
static presentValue(futureValue, rate, periods) {
return futureValue / Math.pow(1 + (rate / 100), periods);
}
// 计算未来值
static futureValue(presentValue, rate, periods) {
return presentValue * Math.pow(1 + (rate / 100), periods);
}
// 计算内部收益率 (IRR) - 简化版本
static irr(cashFlows, guess = 0.1) {
let rate = guess;
let npv;
let derivative;
for (let i = 0; i < 100; i++) {
npv = 0;
derivative = 0;
for (let j = 0; j < cashFlows.length; j++) {
npv += cashFlows[j] / Math.pow(1 + rate, j);
if (j > 0) {
derivative -= j * cashFlows[j] / Math.pow(1 + rate, j + 1);
}
}
const newRate = rate - npv / derivative;
if (Math.abs(newRate - rate) < 1e-10) {
return newRate * 100; // 转换为百分比
}
rate = newRate;
}
return rate * 100; // 转换为百分比
}
// 计算净现值 (NPV)
static npv(rate, cashFlows) {
let npv = 0;
for (let i = 0; i < cashFlows.length; i++) {
npv += cashFlows[i] / Math.pow(1 + (rate / 100), i);
}
return npv;
}
// 计算折旧 (直线法)
static straightLineDepreciation(cost, salvageValue, usefulLife) {
return (cost - salvageValue) / usefulLife;
}
// 计算折旧 (双倍余额递减法)
static doubleDecliningBalance(cost, salvageValue, usefulLife, year) {
const rate = 2 / usefulLife;
let bookValue = cost;
for (let i = 1; i < year; i++) {
bookValue -= bookValue * rate;
}
const depreciation = bookValue * rate;
// 确保不跌破残值
return Math.min(depreciation, Math.max(0, bookValue - salvageValue));
}
// 计算通胀调整后的价值
static inflationAdjustedValue(currentValue, inflationRate, years) {
return currentValue / Math.pow(1 + (inflationRate / 100), years);
}
// 计算购买力
static purchasingPower(initialAmount, inflationRate, years) {
return initialAmount / Math.pow(1 + (inflationRate / 100), years);
}
// 计算 breakeven point
static breakEvenPoint(fixedCosts, pricePerUnit, variableCostPerUnit) {
const contributionMargin = pricePerUnit - variableCostPerUnit;
if (contributionMargin <= 0) {
throw new Error("单价必须大于单位变动成本");
}
return fixedCosts / contributionMargin;
}
}
// 使用示例
const principal = 10000;
const rate = 5;
const time = 10;
console.log("复利:", FinancialCalculator.compoundInterest(principal, rate, time));
// 16288.946267774416
console.log("简单利息:", FinancialCalculator.simpleInterest(principal, rate, time));
// 5000
const loanAmount = 100000;
const annualRate = 5;
const loanTerm = 120; // 10年
console.log("月供:", FinancialCalculator.loanPayment(loanAmount, annualRate, loanTerm));
// 1060.655158137369
console.log("总利息:", FinancialCalculator.loanTotalInterest(loanAmount, annualRate, loanTerm));
// 27278.61909648428
console.log("投资回报率:", FinancialCalculator.roi(1000, 1500)); // 50
console.log("年化收益率:", FinancialCalculator.annualizedReturn(1000, 1500, 5)); // 8.45
console.log("现值:", FinancialCalculator.presentValue(1000, 5, 10)); // 613.91
console.log("未来值:", FinancialCalculator.futureValue(1000, 5, 10)); // 1628.89
const cashFlows = [-1000, 300, 300, 300, 300];
console.log("IRR:", FinancialCalculator.irr(cashFlows)); // 7.71
console.log("NPV:", FinancialCalculator.npv(10, cashFlows)); // 53.46
console.log("直线法折旧:", FinancialCalculator.straightLineDepreciation(10000, 1000, 5)); // 1800
console.log("双倍余额递减法折旧:", FinancialCalculator.doubleDecliningBalance(10000, 1000, 5, 1)); // 4000
console.log("通胀调整价值:", FinancialCalculator.inflationAdjustedValue(1000, 3, 10)); // 744.09
console.log("购买力:", FinancialCalculator.purchasingPower(1000, 3, 10)); // 744.09
console.log("盈亏平衡点:", FinancialCalculator.breakEvenPoint(10000, 50, 30)); // 500总结
JavaScript Math 对象的核心要点:
- 基本概念:静态对象,提供数学常数和函数
- 常数属性:E、PI、SQRT2 等数学常数
- 基本函数:abs()、sign()、floor()、ceil()、round()、trunc()
- 幂和根函数:pow()、sqrt()、cbrt()、hypot()
- 指数和对数:exp()、log()、log10()、log2()
- 三角函数:sin()、cos()、tan() 及其反函数
- 双曲函数:sinh()、cosh()、tanh() 及其反函数
- 最值函数:max()、min()
- 随机函数:random()
- 工具应用:几何计算、金融计算、精确计算等
Math 对象是 JavaScript 中处理数学运算的重要工具,掌握其各种方法对于进行科学计算、数据分析、图形处理等任务至关重要。在下一章节中,我们将学习 JavaScript 的库。