Created On: 31 March 2011
Problem:
First, some background information on intrinsic functions ORD and CHAR:
Intrinsic function ORD takes a single character as an argument, and returns an integer representing the ordinal position of the character in the program collating sequence. Below is sample code with output -- this is not a code fragment, but a complete COBOL program, suitable for cutting-and-pasting:
UNIX prompt > cat demo-ord.cbl
1 01 char-ws pic x value "F".
2 01 ord-ws pic 9(3).
3 move function ord(char-ws) to ord-ws.
4 display "The ordinal position of character ",
5 char-ws, " in the".
6 display "program collating sequence is: ",
7 ord-ws.
UNIX prompt > cob demo-ord.cbl
UNIX prompt > cobrun demo-ord
The ordinal position of character F in the
program collating sequence is: 071
-------------------------------------------------------------
Likewise, intrinsic function CHAR takes an integer argument and returns the alphanumeric character in the program collating sequence at the ordinal position given by the integer:
UNIX prompt > cat demo.cbl
1 01 ord-ws pic 9(3) value 66.
2 display "Character at ordinal position ",
3 ord-ws, " in the".
4 display "program collating sequence is: ",
5 function char(ord-ws).
UNIX prompt > cob demo.cbl
UNIX prompt > cobrun demo
Character at ordinal position 066 in the
program collating sequence is: A
--------------------------------------------------------------
If no ALPHABET is specified in the environment division, the program collating sequence defaults to NATIVE, which defaults to ASCII. Most COBOL programs on Windows and UNIX use ASCII as the program collating sequence.
But there seems to be a discrepancy in the behavior of CHAR and ORD -- the output values seem one greater than expected.
According to the ASCII chart in the documentation, character "A" is equivalent to hex 41, which is decimal 65, and "F" is hex 46, decimal 70. But the CHAR and ORD functions give "A" as 66 and "F" as 71 -- one greater than expected.
Intrinsic function ORD takes a single character as an argument, and returns an integer representing the ordinal position of the character in the program collating sequence. Below is sample code with output -- this is not a code fragment, but a complete COBOL program, suitable for cutting-and-pasting:
UNIX prompt > cat demo-ord.cbl
1 01 char-ws pic x value "F".
2 01 ord-ws pic 9(3).
3 move function ord(char-ws) to ord-ws.
4 display "The ordinal position of character ",
5 char-ws, " in the".
6 display "program collating sequence is: ",
7 ord-ws.
UNIX prompt > cob demo-ord.cbl
UNIX prompt > cobrun demo-ord
The ordinal position of character F in the
program collating sequence is: 071
-------------------------------------------------------------
Likewise, intrinsic function CHAR takes an integer argument and returns the alphanumeric character in the program collating sequence at the ordinal position given by the integer:
UNIX prompt > cat demo.cbl
1 01 ord-ws pic 9(3) value 66.
2 display "Character at ordinal position ",
3 ord-ws, " in the".
4 display "program collating sequence is: ",
5 function char(ord-ws).
UNIX prompt > cob demo.cbl
UNIX prompt > cobrun demo
Character at ordinal position 066 in the
program collating sequence is: A
--------------------------------------------------------------
If no ALPHABET is specified in the environment division, the program collating sequence defaults to NATIVE, which defaults to ASCII. Most COBOL programs on Windows and UNIX use ASCII as the program collating sequence.
But there seems to be a discrepancy in the behavior of CHAR and ORD -- the output values seem one greater than expected.
According to the ASCII chart in the documentation, character "A" is equivalent to hex 41, which is decimal 65, and "F" is hex 46, decimal 70. But the CHAR and ORD functions give "A" as 66 and "F" as 71 -- one greater than expected.
Resolution:
This is because COBOL begins counting the program collating sequence from 1 instead of counting from 0.
A programmer could just take this into consideration, and subtract 1 from the output if necessary.
Another approach is to use the compiler directive ALPHASTART during the declaration of an ALPHABET in the environment division, specifying ALPHASTART"0", to make COBOL begin counting from zero. Here is a sample program:
000001 environment division.
000002 configuration section.
000003 object-computer.
000004 program collating sequence is ascii-offset.
000005 special-names.
000006 $set alphastart"0".
000007 alphabet ascii-offset is
000008 01 thru 128.
000009 working-storage section.
000010 01 char-ws pic x value "A".
000011 01 ord-ws pic 9(8).
000012 move function ord(char-ws) to ord-ws.
000013 exhibit named ord-ws.
This program is applicable to all the following platforms, and was tested successfully on each: Net Express for Windows, as well as Server Express for Solaris, AIX, HP/UX, and Linux.
A programmer could just take this into consideration, and subtract 1 from the output if necessary.
Another approach is to use the compiler directive ALPHASTART during the declaration of an ALPHABET in the environment division, specifying ALPHASTART"0", to make COBOL begin counting from zero. Here is a sample program:
000001 environment division.
000002 configuration section.
000003 object-computer.
000004 program collating sequence is ascii-offset.
000005 special-names.
000006 $set alphastart"0".
000007 alphabet ascii-offset is
000008 01 thru 128.
000009 working-storage section.
000010 01 char-ws pic x value "A".
000011 01 ord-ws pic 9(8).
000012 move function ord(char-ws) to ord-ws.
000013 exhibit named ord-ws.
This program is applicable to all the following platforms, and was tested successfully on each: Net Express for Windows, as well as Server Express for Solaris, AIX, HP/UX, and Linux.
Incident #2119041
Old KB# 33833
#MFDS
#EnterpriseDeveloper