# Range Function

edited April 2020
Recently, I am questioning how the range function works. In examples I have from Waters it seems like the range is inclusive of the boundary. For example:
`ENUM(LT([s/n],100), RANGE([s/n],100,200), GT([s/n],200))</code><code>`
In sections this means if we are less than 100 (e.g. 99.999999), if we are between 100 and 200 (e.g. 100.000000 - 200.000000, and if we are greater than 200 (e.g. 200.000001). I've used a precision of six to illustrate the point (and no calculations are being performed because, this is part of an enumerated (fc) calculation).
Now, given the above, I am trying to do something really simple. I have an average of replicate injections producing a % LC to a precision of 1 (e.g. 98.5%). I have another custom field that looks like:
`<pre class="CodeBlock"><code>RANGE(Average_LC, 98.5, 101.5)*1*1 + LT(Average_LC,98.5)*1*2`
My Average_LC is EXACTLY 98.5 and I'm generating a 0.0 value for this section of code ... this is what makes me think the RANGE function isn't exactly inclusive of the boundary ... However, when I alter the code to:
`RANGE(Average_LC, 98.4, 101.5)*1*1 + LT(Average_LC,98.5)*1*2`

The custom field will return a value of 1.0.
At the end of the day, I am concerned if I am opening the door for potential error by lowering the RANGE to 98.4 as I can't have both parts of the formula coming true and thereby lead to the generation of an erroneous result.

I had a lot of trouble with the RANGE function when coding custom fields a few years ago and like yourself, I found the examples given in various Inform slideshows and even on the Empower Help topics just added to my confusion. I have seen content in Help which is downright wrong and this leaves a bad impression on anyone looking to learn. Taking into account the final precision of your answer is very important when using this function. After a lot of digging and experimenting, I read that you must consider RANGE(X,Y), as RANGE(GT X,LTE Y) so for a CF like RANGE(Height,1000,5000), any and all values greater than 1000, be that 1001 or 1000.000000001 will be included and return a 1 on the translation table. If your value is exactly 1000, this is not GT 1000, and is therefore excluded, and the 0 translation is included.

Getting back to ROUND, which I'm very careful only to use on final reported results as it can cause an enormous margin of error when using rounded values as intermediates on the way to a final value, I pick the precision in the test method or SOP of what's required. For example, I was coding a CF called RANGE(ROUND(Amount,0),98,102) as my Amount was required to 0 decimal places and I just couldn't understand why I was getting a 0 translation for a value of 97.8 which rounds to 98. The reason was it was only looking for values greater than 98 when considered as a whole number, so 98.5 onwards. When I changed it to RANGE(ROUND(Amount,0),97,102) then I captured any values greater than 97 to 0 decimals, so 97.5 onwards.

When using the CConst for these ranges, you need to subtract the relevant lowest decimal value number that's relevant to your field so if USP Resolution needs to be 1.8 to 2.2, then RANGE(ROUND(USPResolution,-1),CConst1-0.1,CConst2) will capture the desired range when 1.8 is in CConst1 because Empower subtracts 1.8-0.1, leaving 1.7, this is your "GT" fixed value so 1.75 onwards will be captured. Same with a range of 98.00 to 102.00. Put 98 in CConst1 and the formula becomes RANGE(ROUND(USP Resolution,-2),CConst1-0.01,CConst2) ie 98-0.01, which is 97.99 and therefore captures any values greater than 97.99 which will generate 98.00 so 97.995 onwards, and so on. Of course you can always just do what you did and have it as RANGE(Custom Field, 98.45,105). Hope this clears it up.

• Hi Empower2019... That's for the very detailed response! I have verified your range function being RANGE(GT X, LTE Y) using some basic test custom fields where I could generate specific numbers and can 100% confirm that this is correct.

I too have found errors in both the Empower online help as well as custom field examples. Unfortunately, I have seen so many examples of RANGE(GTE X, LTE Y) that I always assumed this to be correct, and never had a result on the boundary condition to be able to test. As I mentioned, it took about four years for a result to eb generated that the extremes.

Anyway, it's easy enough to fix. This Average_LC is a final output, at least in terms of uniformity of dosage units, so I am okay with rounding at this point. In addition USP <905> tends to indicate UDU is should be evaluated to one decimal at certain outputs. So, I'll leave Average_LC rounded to one decimal. and setup the RANGE function as RANGE(98.499999,101.5).
• edited April 2020
...and in 4 more years, someone will have a result that is incorrect because there needed to be one or two more 9s at the end of that 98.49...
Perhaps a PCS to correct the schema behind this gaffe is in order? It should be a pretty easy fix in the Oracle workings (GT -> GTE).

Meanwhile, I think I'll make the EXACT same change to my CF for deciding what M is in my CU calculations!
• I would agree and that would make more sense to me in the long one. Why this was coded as GT and LTE makes me thing this was not an intentional act...
• Yep. It goes in the same bin as help file errors, failure to include any tabs in PDF output or sketchy results when attempting to paste data into a sample set or SS method. "Oops. That was a mistake that we missed initially, and now that it's validated, we can't change it without going through *the process*."
• There are a lot of typos and mistakes in the Empower Help section. One particular topic about search order of a peak custom field using Detector Noise as a parameter, the values make no sense at all, its as if they didn't proof it when they released it. The service notes also documents the bugs or glitches from one version of Empower to the next, for instance FR2 to FR5, there are a whole lot of issues being raised. Like any software its not perfect and definitely has its kinks.