When a SOM method is called, a conversion needs to take place from the REXX object to a native SOM type. The method is dispatched using somApply, so some additional conversions occur because the arguments must be passed in a widened form as ANSI defines for va_lists. In general this causes no problems; however in some cases, such as with float or double parameters, a loss of precision may occur because of converting between a double (widened form) and a float. Also because of some rounding conditions, the conversion from the REXX object to a double or float may cause loss of precision.
Keep in mind that the default REXX NUMERIC DIGITS setting is 9 (See the Object REXX Reference for details on NUMERIC). This can cause unexpected results if you call a SOM method and pass it a value greater than 999999999 or less than -999999999. You may want to change the NUMERIC DIGITS setting, for example:
NUMERIC DIGITS 10
if you are using large long or ulong values.
The limits on the various supported SOM types follow:
┌─────────────────┬─────────────────────────┬─────────────────────────┐ │TYPE │MINIMUM │MAXIMUM │ ├─────────────────┼─────────────────────────┼─────────────────────────┤ │boolean │0 (false) │1 (true) │ ├─────────────────┼─────────────────────────┼─────────────────────────┤ │char(*) │'80'x (-128) │'7f'x (127) │ ├─────────────────┼─────────────────────────┼─────────────────────────┤ │double │2.2250738585072014e-308 │1.7976931348623158e+308 │ ├─────────────────┼─────────────────────────┼─────────────────────────┤ │float(**) │1.175494351e-38 │3.402823466e+38 │ ├─────────────────┼─────────────────────────┼─────────────────────────┤ │long │-2147483648 │2147483647 │ ├─────────────────┼─────────────────────────┼─────────────────────────┤ │octet(*) │'00'x (0) │'ff'x (255) │ ├─────────────────┼─────────────────────────┼─────────────────────────┤ │short │-32768 │32767 │ ├─────────────────┼─────────────────────────┼─────────────────────────┤ │unsigned long │0 │4294967295 │ ├─────────────────┼─────────────────────────┼─────────────────────────┤ │unsigned short │0 │65535 │ └─────────────────┴─────────────────────────┴─────────────────────────┘
Note: The use of types char and octet is not always obvious. Because these are treated as "8-bit quantity," the parameter from REXX should be a single character. However, not all characters are exactly representable, so you may need to use the D2C and X2C built-in functions to achieve the desired results (see the Object REXX Reference for details about these functions).
For example, to pass the hexadecimal value 'FF'x to a SOM method as type char you would code:
x2c('FF'x)
Or, if you know the decimal value of the code, you can use it (for example, the decimal equivalent of 'FF'x is -1):
d2c(-1,1)
To convert a returned value back to the decimal equivalent, use the C2D function (see the Object REXX Reference for details). For type char, remember to process the value as a signed number (specify 1 as the second argument of the C2D function).
For example, if a returned value is 'FF'x, then:
c2d(returned_value,1) /* Returns -2 for type char */ c2d(returned_value) /* Returns +254 for type octet */
REXX supports the following parameter or return types: void, short, ushort, long, ulong, float, double, boolean, char, string, octet, objref, pointer, struct, and somId, array, and sequence. The support for the struct type is passthru only. That is, you cannot directly change the individual elements of a structure, but you can receive it as a return and then pass it back out as a method parameter. Array and sequence parameters must be REXX array objects or be capable of returning an array with the MAKEARRAY method.