4

I am using a rule in Coldfusion to tabulate the values of several input fields to verify that they equal 100. This works with whole numbers, but the rule fires if decimal numbers are entered, even when they add up to 100. I inserted the total value into the message string and the warning will say, "These values should add up to 100%, current total is 100". Here is the code for the rule, and also a screenshot showing the result when I enter: 80, 18, 1.5, .1, .1, and .3

Screen shot: enter image description here

Not sure what the problem is...

<!--- Tabulate race --->
    <cfif isNumeric(form.whitePct)>
        <cfset race += #form.whitePct#>
    </cfif>
    <cfif isNumeric(form.blackPct)>
        <cfset race += #form.blackPct#>
    </cfif>
    <cfif isNumeric(form.asianPct)>
        <cfset race += #form.asianPct#>
    </cfif>
    <cfif isNumeric(form.paciPct)>
        <cfset race += #form.paciPct#>
    </cfif>
    <cfif isNumeric(form.amerIndPct)>
        <cfset race += #form.amerIndPct#>
    </cfif>
    <cfif isNumeric(form.othPct)>
        <cfset race += #form.othPct#>
    </cfif>

    <!--- Q60 - Numbers for this question should total 100% --->
    <cfif race neq '100'>
        <cfset queryAddRow(queryLog)>
        <cfset querySetCell(queryLog,"ruleField","whitePct")>
        <cfset querySetCell(queryLog,"ruleMessage","Q60 - Numbers for this question should total 100%, current total is #race#")>
        <cfset querySetCell(queryLog,"ruleGUID","A5DC7FDD-6624-4B0F-A99B-2589B8CBC07D")>
        <cfset querySetCell(queryLog,"ruleType","soft warning")>
        <cfset querySetCell(queryLog,"ruleCategory","RANGE")>
        <cfset querySetCell(queryLog,"ruleOrder","410")>
        <cfset querySetCell(queryLog,"ruleID","1484")>
    </cfif>

Edit: This problem seems to be specifically associated with these numbers in this order. When I enter: .1, .1, .3, 1.5, 18, 80 - the rule does not fire. Now I'm even more confused.

Miguel-F
  • 13,450
  • 6
  • 38
  • 63
  • When in doubt, look at your data. In this case, output the value of race, many times. – Dan Bracuk Mar 08 '17 at 18:58
  • 1
    Your code ` compares the calculated sum with the String '100'. Leave the quotes out to compare numbers. – Bernhard Döbler Mar 08 '17 at 19:07
  • 1
    That particular combination of numbers [works out to 100 in CF11](http://trycf.com/gist/0cf4ce41cb2a2ff5302fa04358b18966/acf?theme=monokai), but it is possible other values do not. CF uses approximate types for most math operations, so while the result may appear to be a round number, that is not always the case . See: http://stackoverflow.com/questions/7422510/why-does-0-06-0-01-0-07-in-coldfusion http://stackoverflow.com/questions/2002821/why-does-this-subtraction-not-equal-zero/2002837#2002837 – Leigh Mar 08 '17 at 19:33
  • (cont'd) if precision matters, use PrecisionEvaluate(). – Leigh Mar 08 '17 at 19:40

1 Answers1

1

As Bernard rightly says, you should compare with 100, not with '100'. But there is another, even more worrisome, issue.

As the input may be decimals, we are in the world of Floats. Here, it is futile to compare using EQ or NEQ. Instead, you work with tolerances.

For example, if your tolerance is 1%, that is, 0.01, then your test will be

<!--- Test for a race value of 100, given a tolerance of 0.01--->
<cfif abs(race-100.0) LT 0.01>

If you set a tolerance to the nearest thousandth, that is, 0.001, then your test will be

<!--- Test for a race value of 100, given a tolerance of 0.001--->
<cfif abs(race-100.0) LT 0.001>
BKBK
  • 484
  • 2
  • 9