Reputation: 1172
Today I have written small program in ColdFusion to find the square root of a number. I found a strange issue. Not sure am I doing any silly mistake ?
<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>
The output is 3.999 instead of 4 when num = 16. Where as when I set it to 36 its output is 6. Not sure why I am getting 3.999 where as it should be 4.Any suggestion?
Upvotes: 2
Views: 95
Reputation: 5388
There is a problem in the if condition. When you use num=36
in that case at 6.001
the if condition gets evaluated and you get 6
. But in the case of num=16
the if condition gets evaluated at 4.00
and you get 3.999
.
But you may ask why at 4.00
it gets evaluated due to floating point numbers and floating point arithmetic.
Edit:
You can use Newton method to find square root of any +ve number.By this method you can achieve better performance over for loop that you had used.
Upvotes: 1
Reputation: 2525
Why do you want to do all the heavy lifting when we can use power of java as below:
<cfset testNumber = 20.50 />
<cfset mathObj = createObject( "java", "java.lang.Math" ) />
<cfset sqrtNumber = mathObj.sqrt(testNumber) />
<cfdump var="#sqrtNumber#"><cfabort>
Output:
4 -> 2
6 -> 2.44948974278
36- > 6
20.50 - > 4.52769256907
As you can see it works on all values including decimals. I hope this helps.
Note: Before passing values to the mathObj.sqrt, you should first check for negative values. You can not have sqrt of negative numbers.
Edit:
As Leigh pointed out there is already a function in CF, you can use that as follows:
<cfset testNumber = 36 />
<cfset sqrtNumber = sqr(testNumber) />
You will get output same as Java version code, only difference is that when you pass negative value in java code, you will get a gibberish value. With CF, you will get an error like this The 1 parameter of the Sqr function, which is now -122.0, must be a non-negative real number.
Upvotes: 1
Reputation: 7193
I altered your code to output the conditions you are seeing like so:
<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>
This outputs all the numbers and the multiples - a long list. The last 3 lines look like this:
3.9999 i * i = 15.99920001
4 i * i = 16
3.9999
That seems like expected behavior to me. Inside your break code you are reducing the value of i with this line:
i = i - n;
Is that not what you want?
Upvotes: 2