如何计算接近无穷大或 0 的极限?
How would one calculate a limit as it approaches infinity or 0?
业余时间我喜欢编写定理程序。
const PI = 3.141592653589793; // Math.PI
function CalculatePi(total = 0, x = 1, addSubBool = false) {
if (addSubBool) {
total -= (4 / x)
console.log(`${total}\tDifference: ${PI - total}`);
} else {
total += (4 / x)
console.log(`${total}\tDifference: ${total - PI}`);
}
if (total !== PI) {
setTimeout(function() {
CalculatePi(total, x + 2, !addSubBool);
}, 100);
}
}
CalculatePi();
这是计算圆周率的递归调用。我基于 this link
我的问题是,如何计算编程中的极限?这个电话会去无穷大。
那么计算器或其他编程语言如何计算 x 接近无穷大时的极限?我会为 x 设置最大值吗?
就个人而言,我会定义一个合适的公差,然后比较当前值和上一个值之间的差异。如果差异低于公差,则停止计算,您知道结果准确到加上或减去您的公差。
您也可以继续计算,直到获得两个相同的值,这可能意味着您已达到存储结果的数据类型的精度限制,任何进一步的计算都没有意义。
下面我们使用loop
和recur
来让你的函数无限循环。我没有使用 setTimeout
,而是尽可能快地重复,而是为每个 1000 x
-
的间隔输出一个结果
const recur = (...values) =>
({ recur, values })
const loop = f =>
{ let acc = f ()
while (acc && acc.recur === recur)
acc = f (...acc.values)
return acc
}
const calculatePi = (limit = Infinity) =>
loop // loop our function ...
( (total = 0, x = 1, addSubBool = false) =>
{ if (x > limit) // stop condition
return total
if (x % 1e3 === 1) // display progress as we go
console.log(x, total, total - Math.PI)
if (total === Math.PI) // solution found
return total
if (addSubBool)
return recur // recur with ...
( total - 4 / x // next total
, x + 2 // next x
, false // next addSubBool
)
else
return recur // recur with ...
( total + 4 / x // next total
, x + 2 // next x
, true // next addSubBool
)
}
)
console.log(calculatePi(1e7))
如您所见,此方法需要很长时间才能收敛到答案。即使经过千万(10M)x,我们仍然只计算了6个点的精度-
x total diff
...
9997001 3.1415924535297624 -2.0006003076389334e-7
9998001 3.1415924535497695 -2.0004002365681117e-7
9999001 3.141592453569776 -2.0002001699381822e-7
另一种方法将 precision
作为 calculatePi
的输入。我们将继续计算直到达到特定精度,而不是受到一些任意 x
的限制。出于演示目的,此函数还 returns x
因此我们可以看到在达到所需精度之前 x
必须达到多大 -
const calculatePi = (precision = 1e5) =>
loop
( (total = 0, x = 1, addSubBool = false) =>
{ if (total * precision >> 0 === Math.PI * precision >> 0)
return [ total, x ]
if (addSubBool)
return recur
( total - 4 / x
, x + 2
, false
)
else
return recur
( total + 4 / x
, x + 2
, true
)
}
)
如你所见,x
超越3700万达到7位小数精度-
console .log
( calculatePi (1e2)
// [ 3.14999586659347, 239 ]
, calculatePi (1e3)
// [ 3.141000236580159, 3377 ]
, calculatePi (1e4)
// [ 3.1415000095284658, 21589 ]
, calculatePi (1e5)
// [ 3.141599999994786, 272243 ]
, calculatePi (1e7)
// [ 3.1415926000000005, 37320609 ]
)
展开下面的代码片段以在浏览器中验证结果 -
const recur = (...values) =>
({ recur, values })
const loop = f =>
{ let acc = f ()
while (acc && acc.recur === recur)
acc = f (...acc.values)
return acc
}
const calculatePi = (precision = 1e5) =>
loop
( (total = 0, x = 1, addSubBool = false) =>
{ if (total * precision >> 0 === Math.PI * precision >> 0)
return [ total, x ]
if (addSubBool)
return recur
( total - 4 / x
, x + 2
, false
)
else
return recur
( total + 4 / x
, x + 2
, true
)
}
)
console .log
( calculatePi (1e2)
// [ 3.14999586659347, 239 ]
, calculatePi (1e3)
// [ 3.141000236580159, 3377 ]
, calculatePi (1e4)
// [ 3.1415000095284658, 21589 ]
, calculatePi (1e5)
// [ 3.141599999994786, 272243 ]
, calculatePi (1e7)
// [ 3.1415926000000005, 37320609 ]
)
最后,在计算 pi 时对照 Math.PI
没有多大意义;我想整个目标是计算一个我们假装不知道的数字。为此,我们从一些 guess
开始,然后测量它与 total
之间的差异。如果猜测在指定的公差范围内,return 猜测 -
const calculatePi = (precision = 1e5) =>
loop
// guess starts at 1
( (guess = 1, total = 0, x = 1, addSubBool = false) =>
{ if (Math .abs (guess - total) * precision < 1)
return [ guess, x ]
if (addSubBool)
return recur // recur with ...
( total // next guess
, total - 4 / x // next total
, x + 2 // next x
, false // next addSubBool
)
else
return recur // recur with ...
( total // next guess
, total + 4 / x // next total
, x + 2 // next x
, true // next addSubBool
)
}
)
我们可以看到它按预期工作。诚然,我对输入精度与计算它所需的 x
之间的相关性感到惊讶 -
console .log
( calculatePi (1e2)
// [ 3.136592684838816, 403 ]
, calculatePi (1e3)
// [ 3.1410926536210413, 4003 ]
, calculatePi (1e4)
// [ 3.1415426535898248, 40003 ]
, calculatePi (1e5)
// [ 3.1415876535897618, 400003 ]
, calculatePi (1e7)
// [ 3.141592603589817, 40000003 ]
)
展开下面的代码片段以在浏览器中验证结果 -
const recur = (...values) =>
({ recur, values })
const loop = f =>
{ let acc = f ()
while (acc && acc.recur === recur)
acc = f (...acc.values)
return acc
}
const calculatePi = (precision = 1e5) =>
loop
// guess starts at 1
( (guess = 1, total = 0, x = 1, addSubBool = false) =>
{ if (Math .abs (guess - total) * precision < 1)
return [ guess, x ]
if (addSubBool)
return recur // recur with ...
( total // next guess
, total - 4 / x // next total
, x + 2 // next x
, false // next addSubBool
)
else
return recur // recur with ...
( total // next guess
, total + 4 / x // next total
, x + 2 // next x
, true // next addSubBool
)
}
)
console .log
( calculatePi (1e2)
// [ 3.136592684838816, 403 ]
, calculatePi (1e3)
// [ 3.1410926536210413, 4003 ]
, calculatePi (1e4)
// [ 3.1415426535898248, 40003 ]
, calculatePi (1e5)
// [ 3.1415876535897618, 400003 ]
, calculatePi (1e7)
// [ 3.141592603589817, 40000003 ]
)
业余时间我喜欢编写定理程序。
const PI = 3.141592653589793; // Math.PI
function CalculatePi(total = 0, x = 1, addSubBool = false) {
if (addSubBool) {
total -= (4 / x)
console.log(`${total}\tDifference: ${PI - total}`);
} else {
total += (4 / x)
console.log(`${total}\tDifference: ${total - PI}`);
}
if (total !== PI) {
setTimeout(function() {
CalculatePi(total, x + 2, !addSubBool);
}, 100);
}
}
CalculatePi();
这是计算圆周率的递归调用。我基于 this link
我的问题是,如何计算编程中的极限?这个电话会去无穷大。
那么计算器或其他编程语言如何计算 x 接近无穷大时的极限?我会为 x 设置最大值吗?
就个人而言,我会定义一个合适的公差,然后比较当前值和上一个值之间的差异。如果差异低于公差,则停止计算,您知道结果准确到加上或减去您的公差。
您也可以继续计算,直到获得两个相同的值,这可能意味着您已达到存储结果的数据类型的精度限制,任何进一步的计算都没有意义。
下面我们使用loop
和recur
来让你的函数无限循环。我没有使用 setTimeout
,而是尽可能快地重复,而是为每个 1000 x
-
const recur = (...values) =>
({ recur, values })
const loop = f =>
{ let acc = f ()
while (acc && acc.recur === recur)
acc = f (...acc.values)
return acc
}
const calculatePi = (limit = Infinity) =>
loop // loop our function ...
( (total = 0, x = 1, addSubBool = false) =>
{ if (x > limit) // stop condition
return total
if (x % 1e3 === 1) // display progress as we go
console.log(x, total, total - Math.PI)
if (total === Math.PI) // solution found
return total
if (addSubBool)
return recur // recur with ...
( total - 4 / x // next total
, x + 2 // next x
, false // next addSubBool
)
else
return recur // recur with ...
( total + 4 / x // next total
, x + 2 // next x
, true // next addSubBool
)
}
)
console.log(calculatePi(1e7))
如您所见,此方法需要很长时间才能收敛到答案。即使经过千万(10M)x,我们仍然只计算了6个点的精度-
x total diff
...
9997001 3.1415924535297624 -2.0006003076389334e-7
9998001 3.1415924535497695 -2.0004002365681117e-7
9999001 3.141592453569776 -2.0002001699381822e-7
另一种方法将 precision
作为 calculatePi
的输入。我们将继续计算直到达到特定精度,而不是受到一些任意 x
的限制。出于演示目的,此函数还 returns x
因此我们可以看到在达到所需精度之前 x
必须达到多大 -
const calculatePi = (precision = 1e5) =>
loop
( (total = 0, x = 1, addSubBool = false) =>
{ if (total * precision >> 0 === Math.PI * precision >> 0)
return [ total, x ]
if (addSubBool)
return recur
( total - 4 / x
, x + 2
, false
)
else
return recur
( total + 4 / x
, x + 2
, true
)
}
)
如你所见,x
超越3700万达到7位小数精度-
console .log
( calculatePi (1e2)
// [ 3.14999586659347, 239 ]
, calculatePi (1e3)
// [ 3.141000236580159, 3377 ]
, calculatePi (1e4)
// [ 3.1415000095284658, 21589 ]
, calculatePi (1e5)
// [ 3.141599999994786, 272243 ]
, calculatePi (1e7)
// [ 3.1415926000000005, 37320609 ]
)
展开下面的代码片段以在浏览器中验证结果 -
const recur = (...values) =>
({ recur, values })
const loop = f =>
{ let acc = f ()
while (acc && acc.recur === recur)
acc = f (...acc.values)
return acc
}
const calculatePi = (precision = 1e5) =>
loop
( (total = 0, x = 1, addSubBool = false) =>
{ if (total * precision >> 0 === Math.PI * precision >> 0)
return [ total, x ]
if (addSubBool)
return recur
( total - 4 / x
, x + 2
, false
)
else
return recur
( total + 4 / x
, x + 2
, true
)
}
)
console .log
( calculatePi (1e2)
// [ 3.14999586659347, 239 ]
, calculatePi (1e3)
// [ 3.141000236580159, 3377 ]
, calculatePi (1e4)
// [ 3.1415000095284658, 21589 ]
, calculatePi (1e5)
// [ 3.141599999994786, 272243 ]
, calculatePi (1e7)
// [ 3.1415926000000005, 37320609 ]
)
最后,在计算 pi 时对照 Math.PI
没有多大意义;我想整个目标是计算一个我们假装不知道的数字。为此,我们从一些 guess
开始,然后测量它与 total
之间的差异。如果猜测在指定的公差范围内,return 猜测 -
const calculatePi = (precision = 1e5) =>
loop
// guess starts at 1
( (guess = 1, total = 0, x = 1, addSubBool = false) =>
{ if (Math .abs (guess - total) * precision < 1)
return [ guess, x ]
if (addSubBool)
return recur // recur with ...
( total // next guess
, total - 4 / x // next total
, x + 2 // next x
, false // next addSubBool
)
else
return recur // recur with ...
( total // next guess
, total + 4 / x // next total
, x + 2 // next x
, true // next addSubBool
)
}
)
我们可以看到它按预期工作。诚然,我对输入精度与计算它所需的 x
之间的相关性感到惊讶 -
console .log
( calculatePi (1e2)
// [ 3.136592684838816, 403 ]
, calculatePi (1e3)
// [ 3.1410926536210413, 4003 ]
, calculatePi (1e4)
// [ 3.1415426535898248, 40003 ]
, calculatePi (1e5)
// [ 3.1415876535897618, 400003 ]
, calculatePi (1e7)
// [ 3.141592603589817, 40000003 ]
)
展开下面的代码片段以在浏览器中验证结果 -
const recur = (...values) =>
({ recur, values })
const loop = f =>
{ let acc = f ()
while (acc && acc.recur === recur)
acc = f (...acc.values)
return acc
}
const calculatePi = (precision = 1e5) =>
loop
// guess starts at 1
( (guess = 1, total = 0, x = 1, addSubBool = false) =>
{ if (Math .abs (guess - total) * precision < 1)
return [ guess, x ]
if (addSubBool)
return recur // recur with ...
( total // next guess
, total - 4 / x // next total
, x + 2 // next x
, false // next addSubBool
)
else
return recur // recur with ...
( total // next guess
, total + 4 / x // next total
, x + 2 // next x
, true // next addSubBool
)
}
)
console .log
( calculatePi (1e2)
// [ 3.136592684838816, 403 ]
, calculatePi (1e3)
// [ 3.1410926536210413, 4003 ]
, calculatePi (1e4)
// [ 3.1415426535898248, 40003 ]
, calculatePi (1e5)
// [ 3.1415876535897618, 400003 ]
, calculatePi (1e7)
// [ 3.141592603589817, 40000003 ]
)