检验方程无理数
Test for equation irrational
我正在做一个数字数据淋浴,它显示一个数字的数据,比如偶数或奇数。现在我停在无理数上,我该如何测试是这样吗?
像这样:
alert(isIrrational(Math.sqrt(9)));
这取决于上下文,但您可能想说,非常接近简单有理数的浮点数应标识为有理数,否则应将它们标识为可能的无理数。你必须选择"非常接近"和"简单有理数"的定义。
对于相对较小的数字(例如绝对值低于 100(,您可能会说简单有理数是分母较小的有理数,例如 2/3,例如分母小于 100 的有理数。您对"非常接近"的定义可能是差异的绝对大小很小,例如低于 10^-6,或者您可能要求数字接近分母平方的 1000 倍。对于大多数目的,这就足够了。
具有小分母的数的有理逼近理论是称为丢番图逼近的数论的一部分。您可能使用的一种工具是数字的简单连续分数扩展,例如 pi = 3+1/(7+1/(15+1/(1+1/292+...)))
和e-1=1+1/(1+1/(2+1/(1+1/(1+1/(4+1/(1+1/(1+1/(6+...))).
您可以递归计算这些,尽管您很快就会耗尽精度。当你截断这样的表达式时,你会得到一个很好的有理近似,比如pi~3,或pi~22/7,pi~355/113,或e~193/71。这些给出候选有理数,其分母很小,非常接近。简单连续分数中的大系数意味着该数字具有良好的有理近似。
数不会以这种方式被检测为有理数,例如,如果对分母使用阈值 100,则为 1/500。但是,您将能够识别 1/3.0f 为理性,而 Math.sqrt(2.0(*Math.sqrt(8.0(,您将拒绝 Math.sqrt(2.0(。
我不知道是否有标准方法来确定像 6.73241 x 10^31 这样的大型浮点数的复杂性。这甚至可以是一个整数,但你没有精度来判断。您可能会说接近平滑整数的数字很简单。平滑意味着素数分解中没有大的素数。虽然分解大数通常很难,但分解平滑数字并不是那么糟糕,因为您只需要测试几个可能的素因数。当您甚至无法测试附近数字的平滑度时,您可以将数字的对数与小素数的对数组合进行比较。这可能意味着大素数不会被识别为有理数,但如果您关心,创纪录的素数通常与平滑数相差 1,例如 2**57885161-1。
在非常大的浮点数和小数之间,您可以使用某种复杂性度量,该度量结合了可能分子的简单性和可能分母的简单性。因此,对于 10^6 和 10^9 之间的数字,您可能会决定只容忍最多 10 的分母,并且您可能要求与其中一个数字的差值小于 10^-4。
确定sqrt(rational)
是否不合理是相当简单的。方法如下:
将rational
参数写为带有m
和n
整数和互质数的m/n
,即gcd(n, m) = 1
。现在假设存在m/n
的有理平方根r
。如果r = s/t
s
和t
整数和互质,我们将有:
s^2/t^2 = rˆ2 = m/n
或
n * s * s = m * t * t
特别是s * s
会除m * t * t
,由于s
和t
没有共同的素数,s * s
实际上会除m
。换句话说,我们将有 (1( s * s <= m
和 (2( m % (s * s) = 0
(mod 操作(。因此,可以使用以下例程非常轻松地计算s
的所有候选项
- [初始化] 设
S
为除数和d := 1
的空集合。 - [选中] 如果
m % (d * d)
= 0,则将d
添加到S
- [增量] 设置
d := d + 1
- [重复] 如果
d * d <= m
转到 2 - [完] 返回
S
以同样的方式,我们可以得出结论,t
满足(1(t * t <= n
和(2(n % (t * t) = 0
。我们可以使用与上面相同的例程来计算n
的所有平方除数的集合T
(只需将S
替换为T
,m
替换为n
(。
最后,我们必须枚举(s, t)
S x T
的所有对
m * s * s = n * t * t
使用精确的整数算术,这是完全可能的。如果没有找到对(s, t)
,那么sqrt(m/n)
将是非理性的。
例
让我们假设我们不知道sqrt(100/81)
是理性10/9
,让我们使用上面给出的算法来推断它:
首先,我们计算 100
的平方除数的集合D
。以下是算法的痕迹:
`d = 1` Yes, `100 % (1 * 1) = 0`
`d = 2` Yes, `100 % (2 * 2) = 0`
`d = 3` No, `100 % (3 * 3) = 1`
`d = 4` No, `100 % (4 * 4) = 4`
`d = 5` Yes, `100 % (5 * 5) = 0`
`d = 6` No, `100 % (6 * 6) = 28`
`d = 7` No, `100 % (7 * 7) = 2`
`d = 8` No, `100 % (8 * 8) = 36`
`d = 9` No, `100 % (9 * 9) = 19`
`d = 10` Yes, `100 % (10 * 10) = 0`
End: `11 * 11 > 100`.
所以,D = {1, 2, 5, 10}
.现在让我们计算T
,81
的平方除数
`d = 1`, Yes
`d = 2`, No (remainder = 1)
`d = 3`, Yes
`d = 4`, No (remainder = 1)
`d = 5`, No (remainder = 6)
`d = 6`, No (remainder = 9)
`d = 7`, No (remainder = 32)
`d = 8`, No (remainder = 17)
`d = 9`, Yes
End: `10 * 10 > 81`.
所以,T = {1, 3, 9}
现在我们枚举D x T
(s, t)
的所有对,并将81 * s * s
与100 * t * t
进行比较。这些对是:
(1, 1), (2, 1), (5, 1), (10, 1)
(1, 3), (2, 3), (5, 3), (10, 3)
(1, 9), (2, 9), (5, 9), (10, 9)
我们看到最后一个(10,9(满足81 * 10 * 10 = 100 * 9 * 9
.因此sqrt(100/81) = 10/9
.如果选择这个例子,使得没有一对满足方程,那么平方根将是无理的。
这是一种可能性。 第一步是找到下一个最小和最大的浮点数(这是导致 prevFloat
和 nextFloat
的各种分配(。 之后,我们逐步浏览所有可能的有理数,分母低于某个阈值,寻找浮点数之间适合的东西。 如果在用完潜在分母之前找不到分数,则会报告 NaN
. 该函数最终在 O(maxDenom)
中运行。
function asRational(number) {
var maxDenom = 1000,
sign = number < 0 ? "-" : "+",
absVal = Math.abs(number),
integer = Math.floor(absVal),
fractionalPart = absVal-integer,
asBinary = fractionalPart.toString(2),
prevAsBinary = asBinary.replace(/10*$/,function(match) {
return "0"+Array(match.length).join("1");
}),
nextAsBinary = asBinary.replace(/01*$/,function(match) {
return "1"+Array(match.length).join("0");
}),
prevFloat = parseFloat(prevAsBinary,2),
nextFloat = parseFloat(nextAsBinary,2),
numerator = 0;
for ( var denominator = 1 ; denominator <= maxDenom ; denominator++ ) {
while ( numerator < denominator*prevFloat ) {
numerator++;
}
if ( numerator <= denominator*nextFloat ) {
return {
"sign":sign,
"integer":integer,
"numerator":numerator,
"denominator":denominator
};
}
}
return NaN;
}
function rationalToString(rational) {
if ( !! rational ) {
return rational.sign+"("+rational.integer
+"+"+rational.numerator+"/"+rational.denominator+")";
} else {
return "NaN";
}
}
function parseFloat(asString,radix) {
var power = asString.length-asString.indexOf(".")-1,
asFloat = parseInt(asString.replace(".",""),radix);
for ( var i = 0 ; i < power ; i++ ) {
asFloat /= radix;
}
return asFloat;
}
var paras = document.getElementsByTagName("p");
for ( var i = 0 ; i < paras.length ; i++ ) {
paras[i].textContent
= paras[i].id+"="+rationalToString(asRational(eval(paras[i].id)));
}
<html>
<head>
</head>
<body>
<p id="5/3"></p>
<p id="100/999"></p>
<p id="99/1000"></p>
<p id="100/1001"></p>
<p id="1000/10000"></p>
</body>
</html>
- java脚本的数学方程显示错误的答案
- 使用方程和/或矢量在三维空间中绘制二维平面
- 如何'unnder'MathJax方程
- Wiris插件正在Tinymce中处理方程保存
- 检验方程无理数
- JavaScript如何处理多变量方程
- Javascript:创建一个随机数学方程数组作为对象,20次
- 使用querySelectorAll从html页面中提取LaTeX方程块
- 使用MathJax的数学方程所见即所得编辑器
- 使用jQuery UI制作一个可拖动的MathML方程
- 从2个点求解指数方程
- 如何在displaystyle(MathJax)中显示asciimath方程
- 用于创建数学减法方程的简单JavaScript算法
- 有选择地使用 MathJax 渲染方程
- 方程的有效算法
- 长方程与覆盖变量
- 将方程转换为 java 脚本可以解释它的方式
- 匹配可变项方程
- 重写 Javascript 方程
- 将一个方程写入Javascript