The truth about the COMP-1 and COMP-2 floating-point fields ...well... to be more precise the truth about COMP-1 and COMP-2 fields in the IBM COBOL mainframe environment.

All computational fields (COMP-x fields) are non-standard fields, they are vendor defined implementations. So this explanation relates to the IBM COBOL mainframe environment.

N.B. The explanation below can be used to write conversion routines to migrate IBM floating-point values to other formats (such as the IEEE standard 754 for binary floating-point arithmetic).

COMP-1 : Is a short-precision floating-point number assigned a full-word in storage (4 bytes, 32 bits).

COMP-2: Is a long-precision floating-point number occupying a double-word (8 bytes, 64 bits).

Following are three examples and explanations of the COMP-1 field and one explanation of the COMP-2 field (using binary,hexadecimal and decimal notations).

The first bit is a sign bit for the entire number. 0 = positive and 1 = negative. Here the first bit is zero therefore the entire number is positive (see plus in +133).

The next 7 bits defines the exponent. Exponents are stored with a bias of 64. This means that any number above 64 defines a positive exponent and any number less than 64 defines a negative exponent. The true value for the exponent is obtained by extracting 64 from the value. The next 7 bits (the 2th through 8th bit) have a bit pattern of b'1000010' = 66 (decimal). The true exponent is therefore 66 û 64 = +2.

The remaining 24 bits (the 9th bit through the last bit (= 32th bit)) is the mantissa. This is the actual digits of the number, expressed as a hexadecimal fraction. To obtain the value of the number, we take the mantissa and shift the radix point the number of places equal to the exponent. The radix point is the period in front of the mantissa. In the decimal numbering system the radix point is called the decimal point. Here the mantissa is: b'10000101 00000000 00000000' = x'85 00 00' Since it is a fraction it has to be written as the hexadecimal value 0.850000 Thus the example above has a mantissa of .850000 and an exponent of 2. Hence, the true number is 85.0000 (hexadecimal) = 133 (decimal).

The sign bit is positive, therefore the whole number is positive.

The next 7 bits, which defines the exponent, has a value of: b'0111111' = 63 decimal. Therefore the exponent is 63 û 64 = -1. A negative exponent means that the radix point is moved to the left instead of the right. The mantissa is x'80 00 00'. thus, the actual number is 0.0800000 (hexadecimal). The decimal value can be calculated as follows: 8 / 16^2 = 0.03125 (the character ^ means 'to the power of' as in 16 'to the power of' 2. Thus, 16^2 = 256).

Explanation COMP-2: COMP-2 is a long-precision floating-point. It has an additional 32 bits more (4 bytes more) than a COMP-1 field. All these additional 32 bits are used for the mantissa making a total of 56 bits for the mantissa. The first 8 bits are defined and used in exactly the same way as in the COMP-1 field previously described.

Hope this information was helpful (to some).

Regards, Wim Ahlers.

Addendum: And now the confusing part...

We humans are used to think in, and calculate with, decimal based numbers (base 10). The computer only knows base 2, which quickly leads to very long numbers (very long strings). To make it a little bit more convenient we divided these binary numbers in groups of three (octal numbering system) and groups of four (hexadecimal numbering system). Since we were short of symbols for the hexadecimal system we invented the characters A through F to represent the decimal values 10 through 15.

Because we are used to the decimal (base 10) system we tend to convert any binary, octal or hexadecimal number back into the decimal system when doing a manual arithmetic calculation.

This conversion is also used in the COMP-1 and COMP-2 examples. The confusing part is this: When the exponent is calculated (+2 and û1 in the examples above) they are to be considered to have a base 10 meaning. This is best to be illustrated with yet another example. Consider the COMP-1 field value of:

In the example above the exponent is defined as b'0110100' = 52. Therefore the exponent is 52 û 64 = -12. This number truly means decimal û12! This is not an octal or hexadecimal number. However, it has a hexadecimal meaning! Confused? This is how it works!

The mantissa is x'85 00 00' which can be described as: .850000 hexadecimal. The exponent is û12. If '.850000' was a decimal number (which it isn't) we would call the period the 'decimal point'. Instead we call it a radix point. Radix is defined as: (numeration system) the positive integer that is equivalent to one in the next higher counting place; "10 is the radix of the decimal system". This means we have to move the radix point 12 places to the left. Notice that the number .850000 is a hexadecimal number and not a decimal number. Therefore every time we move the radix point to the left we divide by the hexadecimal base (divide by 16). So the final result is: 0.000000000000850000 Be aware! This still is a hexadecimal number and not a decimal number. The question now is: What decimal value is the hexadecimal value of 0.000000000000850000? The problem here is that it is a fraction, not a whole number. We solve this as follows:

First shift the radix point to the right until all digits other than (trailing) zeros are on the left side of the radix point. Count how many times the radix point is moved to the right. Result: 85.0000 and the radix point(=period) was shifted 14 places to the right.

Secondly, calculate the decimal value for the hexadecimal value of 85. Result: 85 (hexadecimal) = 133 (decimal)

Finaly divide this number as many times by the hexadecimal base as you shifted the radix point to the right. We shifted 14 times, Therefore the final decimal result is: 133 / 16^14 = 1,8457458E-15 (approximately!).

As an excercise you can count the positive and negative minimum and maximum values. For instance: b'01111111 11111111 11111111 11111111' ,or b'00000001 00000000 00000000 00000001'

Post mortum:

It was pointed out by one of the readers that arithmetic inaccuracies can (still) occur even when the official IEEE standard 754 for binary floating-point arithmetic is used. It is important to realise that any finite floating-point definition also has a finite precision.

To my knowledge, the 754 standard has a higher accuracy, has a defined zero value, has guards on over- and underflow conditions but still has a finite definition. So, it may, given certain conditions, produce incorrect results. However, I am not familiar with the details of the 754 standards myself therefore I can neither confirm nor do I know when, or under which circumstances, this situation may occur.

Credits: Special thanks to Bill, Tom and Glenn for their additional information.