%MAX and %MIN (Maximum or Minimum Value)

%MAX(item1 : item2 {: item3 { item4 ... } })
%MIN(item1 : item2 {: item3 { item4 ... } })

%MAX returns the maximum value of its operands and %MIN returns the minimum value of its operands. Otherwise, the rules and behavior of these built-in functions are identical.

The operands must all have data types that are compatible for comparison with each other. For example, if one item in the list is alphanumeric, the other items can be alphanumeric, UCS-2, or graphic. If one item is packed numeric, the other items can be packed numeric, zoned numeric, integer, unsigned integer, binary decimal, or float.

Items with type procedure-pointer or type object are not allowed as operands.

There must be at least two operands. There is no practical upper limit for the number of operands.

When the built-in function is used in a Declaration statement, there must be exactly two operands; the operands must both be numeric and they cannot be float or hexadecimal.

If any decimal operand has more decimal positions than the result of the operation, half-adjust is used.

If the built-in function is used in a Declaration statement, the result is the operand with the higher (%MAX) or lower (%MIN) value.

The data type of the value returned by the built-in function in calculations depends on the data type of the operands.
  • If all operands are hexadecimal literals, the return value is alphanumeric with CCSID(*HEX). Otherwise, hexadecimal literals are treated as numeric or character depending on the other operands of the built-in function.
  • If all the operands have date type date, the result has data type date with format *ISO.
  • If all the operands have date type time, the result has data type time with format *ISO.
  • If all the operands have data type timestamp, the result has data type timestamp and the number of fractional digits of the returned value is the maximum number of fractional digits of any of the operands.
  • If all the operands have date type pointer, the result has data type pointer.
  • If all the operands have data type Numeric, the following considerations are used to determine the format, length and number of decimal positions.
    • If any operand is float, the returned value is float with a length of 8.
    • Otherwise, if any operand is packed decimal, zoned decimal, or binary decimal, the returned value is packed decimal. The number of integer places is the maximum number of integer places of the operands. The number of decimal positions is the maximum number of decimal positions of the operands. If the number of integer places plus the number of decimal places exceeds 63, the number of decimal positions is reduced so that the total length is 63.
    • Otherwise, if any operand is integer and another operand is unsigned integer, then the returned value is packed decimal with a length of 20 digits and 0 decimal positions.
    • Otherwise, if any operand is integer, the returned value is integer with a length of 20.
    • Otherwise, the returned value is unsigned integer with a length of 20.
  • If all the operands have data type alphanumeric, UCS-2 or graphic, the following considerations are used to determine the data type, length and CCSID:
    • If any operand is alphanumeric with CCSID *UTF-8, the returned value is alphanumeric with CCSID *UTF-8.
    • Otherwise, if any operand is UCS-2, the returned value is UCS-2. If all the UCS-2 operands have the same CCSID, the returned value has that CCSID. Otherwise, the returned value has the default UCS-2 CCSID for the module.
    • Otherwise, if there is a mixture of alphanumeric and graphic operands, the returned value is UCS-2 with the default UCS-2 CCSID for the module.
    • Otherwise, if all the operands are graphic, and all the graphic operands have the same CCSID, the returned value is graphic with the same CCSID as the operands.
    • Otherwise, if all the operands are graphic but with different CCSIDs, the returned value is UCS-2 with the default UCS-2 CCSID for the module.
    • Otherwise, if all the operands are alphanumeric, and all the alphanumeric operands have the same CCSID, the returned value is alphanumeric with the same CCSID as the operands. The job CCSID and the mixed CCSID related to the job CCSID are considered to be the same for this determination. If at least one CCSID is the mixed CCSID related to the job CCSID, then the returned value has that CCSID.
    • Otherwise, if all the operands are alphanumeric but with different CCSIDs, the returned value is alphanumeric with CCSID *UTF-8. The length of the returned value is the maximum length of the operands, or if any CCSID conversions are required, the maximum possible length of the operands converted to the CCSID of the returned value. If this length exceeds the maximum length allowed, the length is reduced to the maximum length. If any alphanumeric or graphic operand has CCSID *HEX, all the operands must have the same data type, alphanumeric or graphic. The returned value has CCSID *HEX only if all the operands have CCSID *HEX.
      Warning: Comparisons in Unicode or ASCII differ from comparisons in EBCDIC. For example, '1' is less than 'A' in Unicode but greater in EBCDIC. Use the %CHAR or %UCS2 built-in function to control the type of the operands if you want to control the CCSID of the comparison and the returned value. To check whether unwanted CCSID conversions are being done for the %MAX or %MIN built-in function, you can specifiy CCSIDCVT(*LIST) in a Control statement, and use with the CCSIDCVT section of the listing to see what CCSID conversions are being done for the statement containing the built-in function.

Examples of %MAX and %MIN

  1. %MAX used in a Declaration statement. The dimension of arr3 is 5, the maximum of the dimensios of arr1 and arr1.
    
       DCL-S arr1 CHAR(10) DIM(3);
       DCL-S arr2 CHAR(10) DIM(5);
       DCL-S arr3 CHAR(10) DIM(%MAX(%ELEM(arr1) : %ELEM(arr2)));
    
  2. %MIN used in a Calculation statement.
    
       DCL-S triangleArea PACKED(7 : 2);
       DCL-S squareArea PACKED(7 : 2);
       DCL-S circleArea PACKED(5 : 2);
       DCL-S size PACKED(7 : 2);
    
       size = %MIN (triangleArea : squareArea : circleArea);