I’ve got a weird rounding issue with Lucee 5.
To reproduce, paste this Code on trycf.com:
result1 = price - (price*discount/100); // 4.1 - 25% => 3.075
writeOutput('result1 => ' & result1 & '<hr />'); // outputs 3.075
resultRounded = Round(result1,2); // this shoud round to 3.08
//resultRounded = NumberFormat(result1,'99999.99'); // workaound, but not nice!?
writeOutput('resultRounded (calculted) => ' & resultRounded & '<hr />'); // outputs 3.07 => wrong!
resultRounded2 = Round(result2,2); // this should round to 3.08
writeOutput('resultRounded2 (fix) => ' & resultRounded2 & '<hr />'); // outputs 3.08 => correct!
if (result1 == result2) writeOutput('results are the same'); else writeoutput(result1 & ' and ' & result2 & ' are not equal!');
Explanation: a price is calculated; it should be 25% of 4.1 which will be 3.075.
The first output just shows the calculated price; 3.075 => correct.
Now, the result should be rounded mathematically to two decimals; result should be 3.08.
BUT => resultRounded outputs 3.07 => wrong!
If I directly set result=3.075 and then do the rounding to that result; output is 3.08 => correct!
Also take a look at the last 3 lines => a dump of both - result1 and result2 - shows both are numbers and both with 3.075. But a comparison of those outputs that they are NOT equal!
Is this a bug?
In the code you see a workaround; if I would use “NumberFormat” of result1 than it will output 3.08. But that’s not “nice”; and also resultRounded would be a string not a number (of course, I could change it to a number with Val(), but that’s definitely not what I want…)
I looked at and tested the round() code and it isn’t that. I have a feeling it is just the Java code behind Lucee during the arithmetic. I haven’t tested if tag version makes a difference versus all cfscript.
Just ran on trycf as tag and it does the same thing. Specifically it is the “-” minus operation. I separated the multiplication and division part to it’s own variable and it still comes out wrong, even if using val() or numberFormat(). If I use numberFormat() or val() or the minus part it comes out correctly.
This happens on all engines in trycf. result1 DOES NOT equal result2 on any engine. ACF or Lucee/Railo.
The problem appears because Railo/Lucee has the precision variable for round() unlike ACF.
You can use val() or numberformat() for arithmetic and then result1 WILL equal result2.
round() with the precision is NOT portable to ACF.