Here’s some more fun with BigDecimal. Use Lucee 6 and turn on “Precise Math” in the admin before running this:
<cfdump eval="1/3"> <!--- string; this never goes into a numeric var --->
<cfset foobar = 1/3> <!--- this is going into a numeric var --->
<cfdump eval="foobar"> <!--- dump of that numeric var --->
The cfdump results are:
string 0.3333333333333333333333333333333333
number 0.3333333333333333
So why do we get 34 places after the decimal when the expression is evaluated as a string and never goes through or into any numeric variable, but only 16 places when it does?
I think I know why, it’s probably because internally, Java handles BigDecimals as strings. However, I’d think because Lucee apparently has code to limit accuracy to 16 places in numeric variables, it’d also have code to limit it to the same 16 places when a numeric variable isn’t involved.
It’s probably rare-to-never that this will present a problem to any of us (how often do you do math with hard-coded string literals like this?) but it’s good to be aware of it.
OS: Linux
Java Version: 11.0.11
Tomcat Version: 8.0.36
Lucee Version: 6.1.0.243
More BigDecimal (“Precise Math”) tests. It looks like when doing calculations or cfdumps, we all ought to be careful and keep everything numeric and avoid:
- string representations of numerics
- string representations of expressions
- numeric expressions passed as strings
<cfset twothirds_numeric = 2/3>
<!--- string value, string exp --->
<cfdump eval="#twothirds_numeric#/2">
<!--- numeric value, string exp --->
<cfdump eval="twothirds_numeric/2">
<!--- numeric value, parentheses-wrapped exp, but still passed as a string --->
<cfdump eval="(twothirds_numeric / 2)">
<!--- numeric value, numeric exp, NOT passed as a string --->
<cfset foobar = twothirds_numeric / 2>
<cfdump eval="foobar">
Output:
string 0.33333333333333335
string 0.3333333333333333333333333333333334
string 0.3333333333333333333333333333333334
number 0.3333333333333333
Notice how the first three results are labelled “string”, and only the last result, which is labelled “number” and was pure numeric throughout (the values, the expression, and how the expression is passed to cfdump), is correct.
Running the code above with “Precise Math” turned off gives this:
number 0.333333333334
number 0.333333333333
number 0.333333333333
number 0.333333333333
Notice they’re all labelled “number”, and the last three values are all correct.
Being careful is clearly warranted when using the new BigDecimal (“Precise Math”) mode. I hope this helps someone.
this is parser vs interpreter, could you raise a ticket for this, we will address it and make it consistent.
BTW using “eval” with cfdump of course is fine, otherwise i would avoid using the interpreter (evaluate) at any coast.
Looking a bit closer at this, i saw that this is already fixed with Lucee 6.1.1
This is the output i get with Lucee 6.1.1
We actually did a lot of improvements with preciseMath in 6.1.1, including improving performance by moving ALL build in functions to use Number arguments, so we do not have to convert between double and Number.
1 Like