Strange cfif behavior

This is maddening.
A simple business calculation I’ve coded a zillion times. (Gross Profit Percent)
I have a little piece of code, and a log file that shows the weirdness.
Obviously, I’m doing something wrong, but what???
The code:

       <!--- log the values --->
	<cfset Msg = "Sales: " &  Sales & " [] GP: " & GP & " [] GPPercent: " & GPPercent>
	<cflog text="#Msg#" file="FebMess" application="false">
       <!--- do the calculation (or not) --->
	<cfif Sales NEQ 0>
		<cfset GPPercent = (GP * 100) / Sales>
	</cfif>
       <!--- log the (new?) values --->
	<cfset Msg = "Sales: " &  Sales & " [] GP: " & GP & " [] GPPercent: " & GPPercent>
	<cflog text="#Msg#" file="FebMess" application="false">

The log file results:

"Severity","ThreadID","Date","Time","Application","Message"
"INFO","ajp-nio-127.0.0.1-8009-exec-6","02/22/2022","22:17:06","","Sales: 0 [] GP: -627.72 [] GPPercent: 0"
"INFO","ajp-nio-127.0.0.1-8009-exec-6","02/22/2022","22:17:06","","Sales: 0 [] GP: -627.72 [] GPPercent: 552148351190040576"

The cfif statement shouldn’t even be firing. … and where is that freaky number coming from?
btw, the cfif fires even if I remove the GP% calculation and simply set that variable to any number.

What in the world am I missing?

Thank You, Thank You in advance.
Any ideas are welcome.

km

Lucee: 5.3.8.206
Apache: 9.0.35
Java: 11.0.7
OS: Windows 2019

I think it happening maybe because of this [LDEV-646] - Lucee.

is variable sales set by arithmetic operations with decimal numbers?

There are no words to express how impressed I am that you knew of that obscure bug.
I bow down to you!
Thank You, Thank You, Thank You.
I had tried int() as a work-around, but not val().
What a weird bug … but the work-around works … so I can get on with my day !!!
Thank You!

To be accurate, the zero I was trying to compare was not set by arithmetic operations.
It was a variable set equal to a db field from a query.
That field was the sum of several records, which did include negatives, and which did add up to zero, but that arithmetic, I would assume, was done by the db engine.
So how it fits into LDEV-646 is still a bit of a mystery.
But the workaround using Val() did the trick.

The trick to find out if an integer you have is actually a floating point number is to output

myVar.toString()

That will reveal what the actual number is behind the scenes, even if it’s being rounded when you output it normaly.

ugh :slight_smile:
I don’t want to output it … I just want to make my calculation and move on.

Thanks,
km

Well, you’ll never solve your “mystery” then ¯_(ツ)_/¯

Should take about 5 seconds to just dump it out. Your call :slight_smile:

I will, of course, be willing to run any test that may help.
But I don’t think this is about outputting strings.
In fact, I am using isNumeric() to qualify the number as I am getting in from the db, so it certainly should not be a string.
The ticket is about making comparisons with numbers arrived at as the result of arithmetic operations involving negative numbers.
I would think any debuggers would be more interesting in knowing that the zero I had trouble with was taken directly from the db engine, and not the result of arithmetic operations. (although the db had to perform arithmetic operations involving negative numbers to produce it)

km

I don’t think you understand what’s being suggested here at all. IF your issue is about floating point ambiguities, then this is EXACTLY about outputting strings! The entire point here is that you think your varaiable contains the numeric value of 0. Perhaps it does. But perhaps it actually contains

0.00000000000000001

which, when output to the page to debug it, is rounded to 0 as a convenience of the CF engine, yet the number may still not actually be equal to 0 in real life. Which is exactly why I’m telling you to stop trusting your cfdump tag or #myVar# code and explicitly ask the underlying Java object to give you a precise string representation of the number. Only then can you definitively determine if it is actually a 0 or just a very-near miss.

No, no. I’m not telling you that you’re getting back a string from the DB! We’re saying you MAY be getting back a number which is a decimal that is very close to 0 but not actually zero. Which is why you need to ask the underlying java Double (most likely) to reveal the exact value. You may not realize this, but ColdFusion engines do automatic rounding when they display decimals to the page so your variable may not have what you think it has.

In fact, I just tested this right now in the CommandBox REPL

CFSCRIPT-REPL: myVar = .0000000000000000000000000001
0
CFSCRIPT-REPL: myVar
0
CFSCRIPT-REPL: myVar.toString()
1E-28

You can see I defined a decimal number which is greater than 0, but Lucee rounds the value to 0 when it displays it. Only when I use myVar.toString() am I able to see the actual value behind the scenes.

I appreciate that you are taking a guess as to what’s in the variable. But instead of guessing, find out! Dump out #myVar.toString()# and then you won’t have to guess. You’ll know. For example, if your number is coming from a Query of Queries, I’ve personally seem them return floating point decimals since they are implemented in Java. But even if it comes from a “real” DB, let’s find out for certain what’s in it.