从厨房烘焙配料、调色板颜色混合,到前端写 CSS aspect-ratio 搞响应式图片排版,“比例(Ratio & Proportion)”可以说是应用最普遍的基础数学工具。

不过在日常开发中,遇到一些具体的工程细节,光凭手算很容易卡壳或写出多余代码:

  • “一张 4032×3024 像素的手机照片,程序怎么用算法自动把它化简成最简整数比 4:3?”
  • “三种原料按 2.5:3.75:1.252.5 : 3.75 : 1.25 配比,如何防浮点误差地扩倍化简为整数连比?”
  • “CSS 中的黄金分割比 ϕ\phi 为什么不仅是美学法则,还能让动态排版的层级结构看起来极具确定感?”

这篇文章我们结合本站 比例与比例方程计算器百分比计算器 的计算内核,把比例的约分算法、连比化简与黄金分割的代数性质讲明白。


1. 比例方程的代数推导与交叉相乘法

比例本质上是两个量之间的相对倍数关系,记作 a:ba : b 或以分数形式书写为 ab\frac{a}{b}(其中 b0b \neq 0)。

当两个比值相等时,构成比例方程(Proportion Equation)

ab=cd\frac{a}{b} = \frac{c}{d}

在代数学中,两边同时乘以分母乘积 b×db \times d,即可消除分母,得到著名的交叉相乘等式(Cross-Multiplication)

ad=bca \cdot d = b \cdot c

根据这一基本恒等式,只要四个变量中有任意三个已知,即可在 O(1)O(1) 时间内精确解出唯一未知数:

x=bcax=adcx = \frac{b \cdot c}{a} \quad \text{或} \quad x = \frac{a \cdot d}{c}

已知:a : b = c : x
求解未知项 x 的几何几何与代数映射:
      a  ───────>  b
      │ ╲       ╱ │
      │   ╲   ╱   │   =>   a · x = b · c   =>   x = (b · c) / a
      │     ╳     │
      │   ╱   ╲   │
      ▼ ╱       ╲ ▼
      c  ───────>  x

浮点运算精度陷阱与防溢出保护

在计算机数值计算中,直接执行 (b * c) / a 在绝大多数情况下非常轻快。但若 bbcc 是超大整数(例如天文或高位密码学数据),b×cb \times c 可能会超出 JavaScript 双精度浮点数(IEEE 754)的 25312^{53}-1 安全整数上限(Number.MAX_SAFE_INTEGER),导致低位精度悄无声息地丢失。

在工程实现上:

  1. 优先使用 ES2020 原生 BigInt 进行整数交叉相乘与模运算;
  2. 若涉及小数,先将两边乘以 10k10^k 转化为整型计算,或者先求出 gcd(a,b)\gcd(a, b) 进行提前约分,减小中间乘积的量级。

2. 连比化简:欧几里得辗转相除法(GCD)

当面临多个量的配比(如混凝土中的水泥、砂、石按 1:2:41 : 2 : 4,或调酒配方中的基酒、果汁、糖浆)时,我们使用的是连续比(Continued Ratio) a:b:ca : b : c

最简整数比算法

若给定一组浮点输入,例如 1.2:0.8:2.01.2 : 0.8 : 2.0

  1. 统一消去小数:找出所有项中小数点后的最大位数 mm,将所有项同步乘以 10m10^m1.2×10=12,0.8×10=8,2.0×10=201.2 \times 10 = 12, \quad 0.8 \times 10 = 8, \quad 2.0 \times 10 = 20

  2. 多项链式最大公约数(GCD): 利用经典的欧几里得辗转相除法(Euclidean Algorithm),两两求 GCD: gcd(a,b,c)=gcd(gcd(a,b),c)\gcd(a, b, c) = \gcd\big(\gcd(a, b), c\big)

    gcd(12,8)=4,gcd(4,20)=4\gcd(12, 8) = 4, \quad \gcd(4, 20) = 4

  3. 同除以整体最大公约数12÷4=3,8÷4=2,20÷4=512 \div 4 = 3, \quad 8 \div 4 = 2, \quad 20 \div 4 = 5 最终输出标准最简连比:3:2:53 : 2 : 5

/**
 * 欧几里得辗转相除法
 */
function gcd(a: number, b: number): number {
  a = Math.abs(a);
  b = Math.abs(b);
  while (b) {
    const temp = b;
    b = a % b;
    a = temp;
  }
  return a;
}

/**
 * 数组全量化简最简整数比
 */
export function simplifyRatio(numbers: number[]): number[] {
  // 1. 统一缩放为整数
  const scales = numbers.map(n => (n.toString().split('.')[1] || '').length);
  const maxScale = Math.pow(10, Math.max(...scales));
  const ints = numbers.map(n => Math.round(n * maxScale));

  // 2. 连续求 GCD
  const commonGcd = ints.reduce((acc, val) => gcd(acc, val));

  // 3. 归一化输出
  return ints.map(val => val / commonGcd);
}

3. 现实工业标准:常见纵横比(Aspect Ratio)

在现代数字显示领域,比例决定了视觉呈现的标准规格:

比例名称 最简比值 典型工业应用场景
16:9 1.777...:11.777... : 1 全球 HDTV、YouTube 视频标准、常见电脑显示器(1080p, 2K, 4K)
16:10 1.6:11.6 : 1 苹果 MacBook 系列屏幕、商务生产力笔记本(纵向视野多出 11.1%
21:9 2.333...:12.333... : 1 影院宽银幕(Anamorphic)、超宽带鱼屏显示器
4:3 1.333...:11.333... : 1 经典 CRT 电视、苹果 iPad 全系平板电脑、中画幅数码摄影
3:2 1.5:11.5 : 1 35mm 全画幅数码单反、微软 Surface 笔记本
1:1 1:11 : 1 经典正方形网格(Instagram 照片流、头像占位)

网页性能:利用 aspect-ratio 阻断布局抖动(CLS)

在前端响应式图片加载中,如果只设置了 width: 100% 而没有指定高度,浏览器在图片下载完成前高度为 0,下载完成后突然撑开内容,导致下方文字瞬间向下弹跳。这被称为 CLS(Cumulative Layout Shift,累积布局偏移),是 Google 核心网页指标(Core Web Vitals)的关键扣分项。

现代 CSS 提供了原生的 aspect-ratio 属性:

.card-cover {
  width: 100%;
  /* 预先占位 16:9 物理比例容器,彻底杜绝回流重排 */
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

4. 黄金分割(Golden Ratio):神秘常数 \phi 的数学本质

如果将一条线段分成两部分,使得较大部分与较小部分之比,恰好等于整条线段与较大部分之比

┌─────────────────────── A ───────────────────────┬────────── B ──────────┐
  (A + B) / A = A / B = φ

ϕ=AB\phi = \frac{A}{B},则有:

1+1ϕ=ϕ    ϕ2ϕ1=01 + \frac{1}{\phi} = \phi \implies \phi^2 - \phi - 1 = 0

解该一元二次方程的正实数根,得到黄金分割常数:

ϕ=1+521.618033988749895...\phi = \frac{1 + \sqrt{5}}{2} \approx \mathbf{1.618033988749895...}

黄金分割与斐波那契数列的极致和谐

斐波那契数列(F0=0,F1=1,Fn=Fn1+Fn2F_0=0, F_1=1, F_n = F_{n-1} + F_{n-2}): 1,1,2,3,5,8,13,21,34,55,89,144,...1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...

当项数趋于无穷大时,后项与前项之比严格收敛于黄金分割比:

limnFn+1Fn=ϕ1.618\lim_{n \to \infty} \frac{F_{n+1}}{F_n} = \phi \approx 1.618

在摄影构图与 UI 栅格系统中,著名的**三分构图法则(Rule of Thirds,1/3 与 2/3 黄金分割近似值)**正是源自该比例的视觉平衡感。