Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

The truth about the COMP-1 and COMP-2 floating-point fields 1

Status
Not open for further replies.

wahlers

Programmer
May 13, 2004
142
NL
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 environment.

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

N.B. The explanation below can be used to write conversion routines to migrate IBM floating-point values to other, non-IBM platforms.

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)

Example 1 (COMP-1, positive number, positive exponent):
b'01000010 10000101 00000000 00000000' = x'42 85 00 00' = +133

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 decimal point the number of places equal to the exponent.
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) which is 133 decimal.

Example 2 (COMP-1, negative number, positive exponent):
b'11000010 10000101 00000000 00000000' = x'C2 85 00 00' = -133

Example 2 is exactly the same as example 1,
except that the sign bit is 1, meaning a negative number (-133 decimal).

Example 3 (COMP-1, positive number, negative exponent):
b'00111111 10000000 00000000 00000000' = x'3F 80 00 00' = +0.03125

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 decimal 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.
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:

b'00110100 10000101 00000000 00000000' = x'34 85 00 00'

In the example above the exponent is defined as b'0110100' = 52.
Therefore the exponent is 52 – 64 = -12.
This number truely 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.
This means we have to move the decimal point 12 places to the left. Notice that the number .850000 is a hexadecimal number and not a decimal number (to be strict we should not say decimal point but hexadecimal point instead. However, I have never seen the expression 'hexadecimal point').
Therefore every time we move the period 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 decimal period to the right until all digits other than (trailing) zeros are on the left side of the decimal period. Count how many times the decimal period is moved to the right. Result:
85.0000 and the 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 divided this number as many times by the hexadecimal base as you shifted the decimal period 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'
 
wahlers said:
to be strict we should not say decimal point but hexadecimal point instead. However, I have never seen the expression 'hexadecimal point'

A useful term is radix point which may be used whatever the radix of the representation.


Catch a star for a very nice technical post. May I suggest that you edit 'decimal point' to 'radix point' and make it a FAQ entry?


Tom Morrison
 
I would also like to make the point that while the author is talking about floating point numbers on IBM mainframes, there is an IEEE floating-point standard which is supported by some COBOL implementations. The page at contains some useful information including links that provide much more depth and detail should one need it.

Regards.

Glenn
 
Tom:
I did as you suggested and posted it on FAQ (Status 2004may22: awaiting review approval)

Glenn:
I added your information as well (the IEEE 754 link).

Tom & Glenn:
You are both credited for your input (see end of article in FAQ).


Regards, Wim Ahlers.
 
You might want to indicate that when you are talking about "IBM environment" - you mean IBM mainframe COBOL.

IBM VisualAge COBOL (and I think - but am not certain COBOL Set) have support to allow the programmer (in COBOL) to select the method described above *or* IEEE for COMP-1 and COMP-2 fields.

Bill Klein
 
Bill Klein:

Thanks! I added your comments to the FAQ entry I created.
You are credited for your input (see end of article in FAQ).

Regards, Wim Ahlers.
 


There are only 10 kinds of programmers;
Those who understand binary, and those who don't.

 
To CobolKid:

D6 D3 C4 40 D1 D6 D2 C5 5A

Regards, Wim.
 
wahlers, I think you left out the D2.
 
To webrabbit:

I have used EBCDIC IBM GX20-1850.
I don't see were I should use your suggested x'D2'.
But then again...english is not my native language!

Regards, Wim.
 
One important thing to remember with IEEE floating point types is that accuracy is not always guaranteed (disseration on why this happens is available upon request). To wit, in the Pascal and Delphi programs I mentioned in the 'telco' benchmark thread it was a constant battle with the floating point types to be able to generate an accurate final result.

In Pascal, it was impossible so the calculations had to be done using user-defined types (longint numbers with a stored precision and functions defined to manipulate and display this user-defined type).

In Delphi however, while still tedious, it was possible to complete the 'telco' benchmark using the floating point types, which are the only way to handle decimal numbers intrinsically. Delphi has a special "currency" type, which is a floating point that is rounded and scaled to 4 decimal places. Used judiciously with careful watch on the results, a degree of accuracy necessary to complete this program was available.

But don't assume 100% accuracy with floating point types.
 
To: glen9999

There is an entry concerning floating-point fields in the FAQ of this forum.
In this FAQ entry there are links to the details of IEEE 754.
I implicitly assume that the reader will read about the details from the links provided in this FAQ entry.


Regards, Wim.
 
Nevertheless it's still important to point out that caveat - that floating point arithmetic is not always 100% accurate.
 
It is also interesting that the ISO 2002 COBOL Standard uses "decimal floating-point" for the "Standard Intermediate Data Item" (SIDI) and this is even MORE accdurate than existing ('85 Standard) for complex arithmatic statements.

Bill Klein
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top