有理数定义为两个整数a和b的商,二者分别称为分子和分母,其中b != 0。
注意,从数学上讲,分母不能为零。 然而在许多有理数的实现中,你会发现分母允许为零,其行为类似于浮点数中的正无穷或负无穷。 在这些情况下,分母和分子一般仍然不能同时为零。
有理数r = a/b的绝对值|r|等于|a|/|b|。
两个有理数r₁ = a₁/b₁和r₂ = a₂/b₂的和为r₁ + r₂ = a₁/b₁ + a₂/b₂ = (a₁ * b₂ + a₂ * b₁) / (b₁ * b₂)。
两个有理数r₁ = a₁/b₁和r₂ = a₂/b₂的差为r₁ - r₂ = a₁/b₁ - a₂/b₂ = (a₁ * b₂ - a₂ * b₁) / (b₁ * b₂)。
两个有理数r₁ = a₁/b₁和r₂ = a₂/b₂的积(乘法)为r₁ * r₂ = (a₁ * a₂) / (b₁ * b₂)。
有理数r₁ = a₁/b₁除以另一个有理数r₂ = a₂/b₂,结果为r₁ / r₂ = (a₁ * b₂) / (a₂ * b₁),前提是a₂不为零。
有理数r = a/b的n次幂(n为非负整数)等于r^n = (a^n)/(b^n)。
有理数r = a/b的n次幂(n为负整数)等于r^n = (b^m)/(a^m),其中m = |n|。
有理数r = a/b的x次幂(x为实数,即浮点数)等于商(a^x)/(b^x),结果是一个实数。
以有理数r = a/b为指数求实数x的幂,等于x^(a/b) = root(x^a, b),其中root(p, q)表示p的q次方根。
实现以下运算:
有理数的实现结果应始终约分到最简形式。
例如,4/4应约分为1/1,30/60应约分为1/2,12/8应约分为3/2,等等。
要约分有理数r = a/b,可将a和b除以a和b的最大公约数(gcd)。
例如,gcd(12, 8) = 4,因此r = 12/8可以约分为(12/4)/(8/4) = 3/2。
有理数约分后的形式应为“标准形式”(分母应始终为正整数)。
如果分母是负整数,就将分子和分母都乘以-1,以确保得到标准形式。
例如,3/-4应约分为-3/4
假设你使用的编程语言没有有理数的实现。
有理数与实数之间的幂运算需要计算一个数的非整数次幂,而 WebAssembly 原生并不支持这一功能。
不过,你也可以把 x ^ y 表示为 x ^ y = exp(y * ln(x))。
幸运的是,我们可以用不同的级数来计算指数函数和自然对数。
计算指数函数最好的方法是用泰勒级数:
exp(x) ≃ 1 + x + x ^ 2 / 2! + x ^ 3 / 3! + x ^ 4 / 4! + ... + x ^ n / n!
高效计算自然对数有多种方法。其中一种是基于反双曲正切的级数:
ln(x) / 2 ≃ y + y ^ 3 / 3 + y ^ 5 / 5 + ... + y ^ n / n where y = (x - 1) / (x + 1)
还有另一种计算自然对数的泰勒级数:
ln(x) = (x - 1) - (x - 1) ^ 2 / 2 + (x - 1) ^ 3 / 3 - (x - 1) ^ 4 / 4 ... + (x - 1) ^ n / n
它只在 x 介于 0 和 2 之间时准确。不过我们也可以用 ln(x) = - ln(1 / x)。
整数幂运算最好用乘法和循环或递归来实现,这既是出于性能考虑,也是出于精度考虑。为了进一步提升性能,可以用霍纳法则来减少乘法的次数。