PeopleCode and SQR: When 1 > 1 (or even 9999) | KEVIN RESCHENBERG 10-31-2014 |
Here for Halloween is some spooky integer math in PeopleCode and SQR.
PeopleCode: Page fields passed as integers
Take a numeric field defined with just a few digits and no decimal places—a 4-digit year, for example. Add it to a derived record and put it on a page.
Then, in some PeopleCode event such as FieldChange, do this:
Function Test(&n as integer)
If &n > 9999 then /* This is TRUE! */
...
Local integer &x = &n;
If &x = &n then /* This is FALSE! */
...
Local float &d = &x - &n;
If &d = 0 then /* But this is TRUE! */
...
If &x = &n + 0 then /* This is TRUE! */
...
End-Function;
Test(MY_RECORD.MY_FIELD.Value);
Go to the page and enter a 1 in the field. What happens? Well, you find out that 1 is greater than 1 (or 2 or 9999 or anything else). What?
I have no explanation, but only advice: Don't pass a numeric field value directly from a page to a function as integer . Pass it as number instead.
(Tested using PeopleTools version 8.51.14)
SQR's FLOOR() function
FLOOR returns a value representing the largest integer that is less than or equal to its argument. Basically, for a positive number, this function
chops off the decimal parts and returns the integer value. But wait:
if floor(21 / 10) = 2 ! This is true
...
if floor(201 / 10) = 20 ! But this is FALSE!
...
This happens only with certain values, and I don't know what the pattern is. Let's explore what SQR thinks that last value is:
let #x = floor(201 / 10)
if #x > 20 ! This is TRUE!
...
if #x - 20 = 0 ! But this is also TRUE!
...
So 20 is greater than 20 but the difference between 20 and 20 is 0. Even though SQR uses binary arithmetic, it should be able to represent an integer value
exactly in a non-typed (floating-point) numeric variable.
(Tested using SQR for PeopleSoft/8.51.14/PC/Windows NT/Oracle/Oct 27 2011. Fortunately, it has been fixed in some later version as it does not occur
in 11.1.1.1.0.920. However, PeopleSoft shops generally use the earlier PeopleSoft versions of SQR.)
So how do I wrap this up? Let's see... How about this: Be sure to test your code...
|