Question

I have problems working with large numbers and long decimal numbers, as others have mentioned or solved such issue using PrecisionEvaluate, I could not get consistent result with such function.

Example with this code :

<cfset n = 0.000000000009>
<cfoutput>#precisionEvaluate(n)#</cfoutput> // this will produce "9E-12"
<cfoutput>#precisionEvaluate("n")#</cfoutput> // this will produce "0.000000000009"

According to Adobe Documentation, using Quote is not recommended (due to processing inefficiency) as well as it should produce same result, however this is not the case from the above code.

Further trials with inconsistent result:

<cfset n = 0.000000000009>
<cfset r = 12567.8903>
<cfoutput>#precisionEvaluate(r * n)#</cfoutput> // this will produce "1.131110127E-7"
<cfoutput>#precisionEvaluate("r * n")#</cfoutput> // this will produce "1.131110127E-7", same as above
<cfoutput>#precisionEvaluate(r / n)#</cfoutput> // this will produce "1396432255555555.55555555555555555556"
<cfoutput>#precisionEvaluate("r / n")#</cfoutput> // this will produce "1396432255555555.55555555555555555556", same as above

Has anybody run into problems with a similar case? What is a practical solution to address the inconsistency? I have tried : using val() function does not resolve as it is limited to short numbers only, using numberFormat() function which is difficult as we have to pass number of decimals to format it properly.

Was it helpful?

Solution

When it comes to numbers, do not always believe what you see on the screen. That is just a "human friendly" representation of the number. In your case, the actual results (or numbers) are consistent. It is just a matter of how those numbers are presented ..

PrecisionEvaluate returns a java.math.BigDecimal object. In order to display the number represented by that object inside <cfoutput>, CF invokes the object's toString() method. Per the API, toString() may use scientific notation to represent the value. That explains why it is used for some of your values, but not others. (Though with or without the exponent, it still represents the same number). However, if you prefer to exclude the exponent, just use BigDecimal.toPlainString() instead:

toPlainString() - Returns a string representation of this BigDecimal without an exponent field....

Example:

<cfscript>
    n = 0.000000000009;
    r = 12567.8903;
    result = precisionEvaluate(r * n);

    WriteOutput( result.getClass().name );
    WriteOutput("<br />result.toString() ="&  result.toString());
    WriteOutput("<br />result.toPlainString() ="&  result.toPlainString());
</cfscript>

Result:

java.math.BigDecimal
result.toString() =1.131110127E-7
result.toPlainString() =0.0000001131110127 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top