Skip to content

JavaScript Math

Math 对象是 JavaScript 的内置对象,提供了各种数学常数和数学函数。它是一个静态对象,所有属性和方法都直接通过 Math 对象访问,而不需要创建实例。在本章节中,我们将深入学习 JavaScript 中的 Math 对象及其各种数学方法。

什么是 Math 对象

Math 对象为数学常数和函数提供了属性和方法。与其他全局对象不同,Math 不是一个构造函数,不能使用 new Math() 创建实例。

Math 对象的特点

  1. 静态对象:所有属性和方法都是静态的
  2. 不可实例化:不能创建 Math 的实例
  3. 内置对象:JavaScript 环境自带
  4. 跨平台:在所有 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)); // true

2. 金融计算工具

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 对象的核心要点:

  1. 基本概念:静态对象,提供数学常数和函数
  2. 常数属性:E、PI、SQRT2 等数学常数
  3. 基本函数:abs()、sign()、floor()、ceil()、round()、trunc()
  4. 幂和根函数:pow()、sqrt()、cbrt()、hypot()
  5. 指数和对数:exp()、log()、log10()、log2()
  6. 三角函数:sin()、cos()、tan() 及其反函数
  7. 双曲函数:sinh()、cosh()、tanh() 及其反函数
  8. 最值函数:max()、min()
  9. 随机函数:random()
  10. 工具应用:几何计算、金融计算、精确计算等

Math 对象是 JavaScript 中处理数学运算的重要工具,掌握其各种方法对于进行科学计算、数据分析、图形处理等任务至关重要。在下一章节中,我们将学习 JavaScript 的库。

本站内容仅供学习和研究使用。