Formats for NUMERIC and DECIMAL data types vary as a function of precision. The value must be right-padded with zeros to the full scale of the value. The value must also be fully left-padded with zeros, but, with binary programming, padding happens automatically. Once the values are padded, the decimal point is removed. For example, the value 12.34 looks like:
NUMERIC(4,2): 1234
NUMERIC(6,4): 123400
NUMERIC(8,4): 00123400
NUMERIC(12,6): 000012340000
NUMERIC(16,8): 0000001234000000
After the value is padded and the decimal point is removed, these rules apply:
If precision <= 4, binary format is identical to native operating system binary format for 2-byte integer quantity.
If precision is between 5 and 9, binary format is identical to native operating system binary format for a 4-byte integer quantity.
If precision is between 10 and 18, binary format is identical to native operating system binary format for an 8-byte integer quantity.
If precision >= 19, there is a special format that uses this C++ struct definition:
struct { unsigned char sign; // sign 1 for +, 0 for - unsigned char ndig; // # digits unsigned char exp; // exponent unsigned char erracc; // should be 0 unsigned short digits[80]; };
Exponent is excess-80 form, unless the value is zero. A “zero” value is represented as:
sign = 1 ndig = 0 erracc = 0 exp = 0
The maximum exponent value is 159. The maximum number of supported digits is 288. “digits[0]” contains the least-significant digits. Digits are stored in a packed representation with two digits per “unsigned short” (2-byte) quantity. For a given “digit:”
lower order digit = digit[i] & 0x00FF
high order digit = digit[i] & 0xFF00
For example, consider the value 100 represented as NUMERIC(20). The binary layout of this value is:
0x0101 0x5000 0x0064 0x0000 0x0000 ...... Sign = 0x01 Number digits = 0x01 Exponent = 0x50 Erracc = 0x00 Digits = 0x0064
As another example, consider the value 32769:
0x0102 0x5000 0x0ad1 0x0003 0x0000 0x0000 .... Sign = 0x01 Number digits = 0x02 Exponent = 0x50 Erracc = 0x00 Digits = 0x0ad1 0x0003
If you translate the digits into base 10, you have:
0x0ad1 = 2769 0x0003 = 3