Conversions from REXX Objects to C/SOM Method Argument Types

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 */