覆盖 90% 编程问题的五大数学运算

发布: (2026年3月25日 GMT+8 10:02)
5 分钟阅读
原文: Dev.to

Source: Dev.to

经过多年构建工具和审查代码,我发现生产软件中绝大多数的数学运算可以归结为五类。你不需要数学学位,只需要在这五个领域熟练掌握。

1. 百分比计算

百分比无处不在:折扣、税金、小费、进度条、分析仪表板、A/B 测试结果。

// What is X% of Y?
const percentOf = (percent, total) => (percent / 100) * total;

// What percentage is X of Y?
const whatPercent = (part, total) => (part / total) * 100;

// Percentage change from A to B
const percentChange = (oldVal, newVal) =>
  ((newVal - oldVal) / oldVal) * 100;

百分比变化公式是开发者最常弄错的。分母是 值,而不是新值。把 50 提升到 75 是 50 % 的增长。把 75 降到 50 是 33.3 % 的下降。这种不对称性会让人困惑。

2. 线性插值

将一个值从一个范围映射到另一个范围。常用于动画、数据可视化、颜色渐变、音频处理和传感器校准。

function lerp(value, inMin, inMax, outMin, outMax) {
  return outMin + ((value - inMin) * (outMax - outMin)) / (inMax - inMin);
}

// Map a 0‑1023 sensor reading to 0‑100%
lerp(512, 0, 1023, 0, 100); // 50.05%

// Map a 0‑1 progress value to a 200‑800px width
lerp(0.75, 0, 1, 200, 800); // 650px

逆向函数(用于确定一个值在范围中的位置)同样有用:

function inverseLerp(value, min, max) {
  return (value - min) / (max - min);
}

// Where does 650 fall in the 200‑800 range?
inverseLerp(650, 200, 800); // 0.75

3. 四舍五入和精度

JavaScript 的浮点运算会产生著名的惊人结果:

0.1 + 0.2 // 0.30000000000000004

一个实用的显示修正方法:

function round(value, decimals) {
  return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
}

round(0.1 + 0.2, 2); // 0.3

对于金融计算,绝不要使用浮点数。使用整数(分):

// 错误写法
const price = 19.99;
const tax = price * 0.08; // 1.5992000000000002

// 正确写法
const priceCents = 1999;
const taxCents = Math.round(priceCents * 0.08); // 160
const totalCents = priceCents + taxCents; // 2159
const totalDollars = (totalCents / 100).toFixed(2); // "21.59"

4. 模运算

取模运算符 (%) 用于在数组中循环、值的环绕、判断奇偶以及时间计算。

// Cycle through an array
const colors = ['red', 'green', 'blue'];
const color = colors[index % colors.length];

// Wrap a value within bounds
function wrap(value, min, max) {
  const range = max - min;
  return ((value - min) % range + range) % range + min;
}

// Convert seconds to hours:minutes:seconds
function formatTime(totalSeconds) {
  const hours = Math.floor(totalSeconds / 3600);
  const minutes = Math.floor((totalSeconds % 3600) / 60);
  const seconds = totalSeconds % 60;
  return `${hours}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
}

wrap 中的双取模用于处理负数。JavaScript 的 % 运算符对负被除数会返回负结果,这通常不是我们想要的。

5. 基本统计

均值、中位数和标准差用于监控、告警、数据分析和性能测量。

const mean = arr => arr.reduce((a, b) => a + b, 0) / arr.length;

const median = arr => {
  const sorted = [...arr].sort((a, b) => a - b);
  const mid = Math.floor(sorted.length / 2);
  return sorted.length % 2
    ? sorted[mid]
    : (sorted[mid - 1] + sorted[mid]) / 2;
};

const stdDev = arr => {
  const avg = mean(arr);
  const variance = mean(arr.map(x => (x - avg) ** 2));
  return Math.sqrt(variance);
};

标准差告诉你数据的离散程度。对于监控而言,如果某个指标偏离均值超过 2 个标准差,就说明出现了异常。这是大多数异常检测系统的基础。

组合它们

真实的问题往往涉及多个操作。比如“为文件上传显示带有百分比和预计剩余时间的进度条”:

function uploadProgress(bytesUploaded, totalBytes, elapsedMs) {
  const percent = whatPercent(bytesUploaded, totalBytes);
  const rate = bytesUploaded / elapsedMs; // bytes per ms
  const remaining = (totalBytes - bytesUploaded) / rate;

  return {
    percent: round(percent, 1),
    barWidth: lerp(percent, 0, 100, 0, 300), // 300px bar
    remainingSeconds: Math.ceil(remaining / 1000)
  };
}

在进行任何数学计算并提供逐步解答时,我会使用位于 . 的求解器。它能够处理从基础算术到代数和统计的所有内容——快速、免费,并且会展示解题过程。

0 浏览
Back to Blog

相关文章

阅读更多 »

网络怀旧

概述 我一直对互联网的快速演变感到着迷。从90年代那种杂乱、色彩斑斓的网站,到今天的简洁、极简设计——它……

Show HN: 字母时钟

请提供您希望翻译的具体摘录或摘要内容,我才能为您进行翻译。