Algorithm 寻找从0.1到10的数字立方体,什么';这个算法有什么问题?
我目前正在为我的离散结构课程做一个实践作业,作业如下: “下面的算法表示试图以0.1的步骤打印出一个从0.1到10的数字立方体表。解释如果在计算机上实现该算法可能出现的问题:Algorithm 寻找从0.1到10的数字立方体,什么';这个算法有什么问题?,algorithm,pseudocode,discrete-mathematics,Algorithm,Pseudocode,Discrete Mathematics,我目前正在为我的离散结构课程做一个实践作业,作业如下: “下面的算法表示试图以0.1的步骤打印出一个从0.1到10的数字立方体表。解释如果在计算机上实现该算法可能出现的问题: x = 0.0 Repeat x = x + 0.1 x_cubed = x^3 Output x, x_cubed until x = 10.0 这是伪代码,所以我不认为错误与语法有关。 我用java重写代码并运行它。如果我把(x!=10.0)作为一个条件,程序永远不会停止,因为出于某种
x = 0.0
Repeat
x = x + 0.1
x_cubed = x^3
Output x, x_cubed
until x = 10.0
这是伪代码,所以我不认为错误与语法有关。
我用java重写代码并运行它。如果我把(x!=10.0)作为一个条件,程序永远不会停止,因为出于某种原因,0.2+0.1会导致0.300000000000000004,这使得x永远不会精确地变成10.0。然而,我不知道这是否是教授正在寻找的问题,因为它可能是Eclipse或java问题 谁能帮我做这个练习吗?
谢谢!问题是,大多数情况下,比较浮点值是否相等(
直到x=10.0
)都是正确的。在您的特定情况下,一种解决方案是在循环中使用整数,必要时使用另一个浮点值
int i = 0
float x = 0.0
Repeat
i = i + 1
x = x + 0.1
x_cubed = x^3
Output x, x_cubed
until i = 100
辩证法是正确的:比较计算出的浮点数是否相等是危险的。由于一些数字不能完全用基数2表示(例如,0.1),这些数字只能大致正确
你可以使用他所建议的整数,但是我会做一个进一步的调整:而不是计算x[n+1]=x[n+dx,考虑x[n+1]=dx*i[n+1]的计算。换句话说,不要使用重复加法(它会随着时间积累大的误差)。;相反,在每次迭代时,从被迭代的整数和浮点步长(本例中为0.1)计算x的从头值。这不会以相同的方式随时间累积错误。我鼓励您通过比较每一步通过重复加法和直接乘法获得的第一百万个值来尝试此方法
编辑:我有一分钟的空闲时间,所以我决定自己做这个测试<html>
<head>
<title>
Floating Point Test
</title>
</head>
<body>
<input type="button" id="btnRun" value="Run" onclick="run();" />
<br/>
<textarea id="txtOutput" rows=20 cols=50></textarea>
<script language="javascript">
function run() {
var add = 0.0;
var mul = 0.0;
var i = 0;
var dx = 0.1;
var lastPower = 1;
var output = "";
for (i = 0; i < 1000000000; i++) {
add = add + dx;
mul = dx * (i + 1);
if (i + 1 >= lastPower) {
output += "i=" + i + ", add=" + add + ", mul=" + mul + "\n";
lastPower *= 10;
}
}
document.getElementById("txtOutput").value = output;
}
</script>
</body>
</html>
这回答了你的问题吗?“我不知道这是否是教授正在寻找的问题”-是的,我猜是这样,至少当x是浮点类型(与某些语言的十进制类型相反)时,x永远不会精确到10.0。我想这是在这个算法中发现的问题。测试应该看起来像
abs(x-10.0)
其中epsilon
是一个小数字(通常为10E-6或更小)@SergeBallesta对于这个简单的情况来说,复杂的方法是,x>=10.0
就可以了。@GyroGearless:abs(x-val)
是在浮点世界中测试伪相等性最常用的习惯用法。这就是我建议使用它的原因。顺便说一句,x>=10.0
需要第二次测试,因为is可以在10.0+epsilon或11.0-epsilon处停止。。。
i=0, add=0.1, mul=0.1
i=9, add=0.9999999999999999, mul=1
i=99, add=9.99999999999998, mul=10
i=999, add=99.9999999999986, mul=100
i=9999, add=1000.0000000001588, mul=1000
i=99999, add=10000.000000018848, mul=10000
i=999999, add=100000.00000133288, mul=100000
i=9999999, add=999999.9998389754, mul=1000000
i=99999999, add=9999999.98112945, mul=10000000
i=999999999, add=99999998.74541782, mul=100000000