此代码在deltanum = 0.0000000000001
时给出非常准确的结果,但是在deltanum = 0.00000000000001
时进入无限循环(向deltanum
添加另一个零)。
它仅在非完美的多维数据集上出现,对于1000这样的完美多维数据集也可以正常工作。为什么?
我是OSSU之后的编程新手。
num = 100
high = num
low = 0
icount = 0
cuberoot = (high + low)/2 #cuberoot of num
deltanum = 0.00000000000001
while abs(cuberoot**3 - num)>=deltanum:
icount+=1
print(icount)
if cuberoot**3 > num:
high = cuberoot
elif cuberoot**3 < num:
low = cuberoot
else:
break
cuberoot = (high + low)/2
print("Cube root: " + str(cuberoot))
print("Number of iterations: " + str(icount))
答案 0 :(得分:2)
您正在使用<canvas id="c"></canvas>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r102/three.min.js"></script>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r102/js/controls/OrbitControls.js"></script>
s。 float
数学在精确度方面是有缺陷的-您的增量可能太小而无法正常工作,并且您的解决方案会在数值之间翻转而从未达到您的float
条件限制。有关为什么有时会“中断”浮动的更多原因,请参见Is floating point math broken?。
您也可以将其限制为一定的重复次数:
while
输出:
num = 100
high = num
low = 0
icount = 0
maxcount = 100000
cuberoot = (high + low)/2 #cuberoot of num
deltanum = 0.00000000000001
while abs(cuberoot**3 - num)>=deltanum:
icount+=1
print(icount)
if cuberoot**3 > num:
high = cuberoot
elif cuberoot**3 < num:
low = cuberoot
else:
break
cuberoot = (high + low)/2
if icount > maxcount:
print("Unstable solution reached after ",maxcount, "tries")
break
print("Cube root: " + str(cuberoot) + " yields " + str(cuberoot**3))
print("Number of iterations: " + str(icount))
答案 1 :(得分:0)
大多数人会用epsilon
来命名,并将delta
用在cuberoot**3 - num
上。
最后,您希望这个表达式,
cuberoot = (high + low)/2
在每次迭代中,您的答案将为您带来大约一点点的精度。 (在开头附近,每次大约将错误位的数量减少一半。)
您在抱怨IEEE-754 double在计算多维数据集时精度有限,并且差异也很大。
53位几乎为16位十进制数字,您的epsilon为1e-14
。
但是,您发现,输入num
长几位数会吃掉您的空白。
对于更高精度的计算,您可能更喜欢使用Decimal。 或者,查看gmp库。
您相信某个循环不变式成立,
cuberoot
和cuberoot ** 3
的数量将在每次迭代中改变。
验证很简单。
只需将它们分配给临时变量,并验证它们是否已更改。
如果没有,请尽早终止循环。
更一般而言,要检测少数几个极限值之间的振荡,请将先前的值放入set
中,并在看到重复值时尽早终止。