Can somebody explain to me why ColdFusion (tested on 2016,2018 and 2021) is doing a wrong double to long conversion? I know it can mess things up for fractional values, but in this example, it is clearly an integer value.
This is the code:
<cfoutput>
<cfset a = 69.35>
#getMetadata(a)# #a#</br>
<cfset b = a * 100>
#getMetadata(b)# #b#</br>
<cfset c = int(b)>
#getMetadata(c)# #c#</br>
</cfoutput>
And this is the output:
class coldfusion.runtime.CFDouble 69.35
class java.lang.Double 6935
class java.lang.Long 6934
It is "sort-of" fixable by doing this:
<cfset d = int(javacast("string", b))>
#getMetadata(d)# #d#</br>
Returning
class java.lang.Long 6935
But I'm not really satisfied by this "solution"... Thanks!
EDIT: Because ColdFusion is running on top of java, I guess this is responsible for it:
public static void main(String[] args)
{
double a = 69.35;
double b = a * 100;
System.out.println(b);
long c = (int)b;
System.out.println(c);
long d = Math.round(b);
System.out.println(d);
}
Output:
6934.999999999999
6934
6935
And most likely, ColdFusion is using int() and not round() to convert the double value to long... This is one of the "nice" side effects of a typeless programming language, which internally makes a mess of it. Makes me think of javascript ;-)
EDIT 2:
As Cameron pointed out, there is a difference between #b# and #b.ToString()#. The former is returning 6935, while the latter is returning 6934.999999999999. This is confusing in my opinion, but I'll keep it in the back of my head for in case I run into another strange problem with double/long values :-)
And to make it even a bit more confusion: int(ToString(b)) is returning 6935 while int(b.ToString()) is returning 6934...
<cfset a = 69.35>
#getMetadata(a)# #a#</br>
<cfset b = a * 100>
#getMetadata(b)# #b#</br>
#b.toString()# #ToString(b)#</br>
Is returning:
class java.lang.String 69.35
class java.lang.Double 6935
6934.999999999999 6935
So, don't assume that b.ToString() is the same as ToString(b) ...