今天我在ColdFusion中编写了一个小程序来查找数字的平方根。我发现了一个奇怪的问题。不确定我是否犯了任何愚蠢的错误?
<cfscript>
num = 16;
n = 0.0001;
i = 0;
for (i=0;i<num;i=i+n)
{
if((i*i)>num){
i = i - n;
break;
}
}
writedump(i);
</cfscript>
当num = 16时,输出为3.999而不是4.当我将其设置为36时,其输出为6。 不知道为什么我得到3.999应该是4.Any建议?
答案 0 :(得分:2)
我改变了你的代码以输出你所看到的条件:
<cfscript>
num = 16.00;
n = 0.0001;
i = 0;
for (i=0;i<num;i=i+n)
{
writeoutput(i & " i * i = " & (i*i));
writeoutput('<br>');
if((i*i)>num){
i = i - n;
break;
}
}
writedump(i);
writeoutput('<br>');
</cfscript>
输出所有数字和倍数 - 长列表。最后3行看起来像这样:
3.9999 i * i = 15.99920001
4 i * i = 16
3.9999
这对我来说似乎是预期的行为。在您的中断代码中,您将使用以下行减少i的值:
i = i - n;
这不是你想要的吗?
答案 1 :(得分:1)
if条件有问题。当您在num=36
处使用6.001
时,if条件会被评估,并且您获得6
。但是在num=16
的情况下,if条件会在4.00
进行评估,并且您得到3.999
。
但是你可能会问为什么4.00
由于floating point numbers和浮点运算而得到评估。
修改强>
您可以使用Newton method查找任何+ ve数的平方根。通过此方法,您可以获得比使用过的循环更好的性能。
答案 2 :(得分:1)
当我们使用java的强大功能时,你为什么要做所有繁重的工作,如下所示:
<cfset testNumber = 20.50 />
<cfset mathObj = createObject( "java", "java.lang.Math" ) />
<cfset sqrtNumber = mathObj.sqrt(testNumber) />
<cfdump var="#sqrtNumber#"><cfabort>
输出:
4 -> 2
6 -> 2.44948974278
36- > 6
20.50 - > 4.52769256907
正如您所看到的,它适用于所有值,包括小数。我希望这会有所帮助
注意:在将值传递给 mathObj.sqrt 之前,应首先检查负值。你不能有负数的sqrt。
的修改:
正如Leigh指出CF中有already a function,您可以按如下方式使用:
<cfset testNumber = 36 />
<cfset sqrtNumber = sqr(testNumber) />
您将获得与Java版本代码相同的输出,唯一的区别是当您在java代码中传递负值时,您将获得一个乱码值。使用CF,您将收到类似 Sqr函数的1参数(现为-122.0,必须为非负实数)的错误。