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'
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'