According to the IBM Informix docs:
DECIMAL(p, s)
values are stored internally with the first byte representing a sign bit and a 7-bit exponent in excess-65 format.
How does the "excess-65" format work?
The notation is specific to Informix and its DECIMAL and MONEY types — AFAIK, no other product uses it. Informix also uses it within its DATETIME and INTERVAL types, but that's an implementation detail for the most part.
I've always know the on-disk form as 'excess-64' rather than 'excess-65'; I'm not sure which is correct, but I think 64 has a solid basis.
The 'excess-6n' form is used for disk storage. It has the benefit that two decimal values in the disk format can be compared using memcmp()
to get a correct comparison (though NULL values have to be handled separately — NULL values always cause pain and grief).
The decimal.h
header from ESQL/C (and C-ISAM) contains the information:
/*
* Packed Format (format in records in files)
*
* First byte =
* top 1 bit = sign 0=neg, 1=pos
* low 7 bits = Exponent in excess 64 format
* Rest of bytes = base 100 digits in 100 complement format
* Notes -- This format sorts numerically with just a
* simple byte by byte unsigned comparison.
* Zero is represented as 80,00,00,... (hex).
* Negative numbers have the exponent complemented
* and the base 100 digits in 100's complement
*/
Note the mention of 64 rather than 65. Also note that 'decimal' is in some respects a misnomer; the data is represented using a 'centesimal' (base-100) notation.
Here are some sample values, decimal representation and then bytes for the on-disk format. Note that to some extent, the number of bytes is arbitrary. If using something like DECIMAL(16,4), there will be 1 byte sign and exponent and 8 bytes of data (and the range of exponents will be limited). If you use DECIMAL(16) — for floating point — then the range of exponents is much less limited.
Decimal value Byte representation (hex)
0 80 00 00 00 00
1 C1 01
-1 3E 63
9.9 C1 09 5A 00
-9.9 3E 5A 0A 00
99.99 C1 63 63 00 00 00
-99.99 3E 00 01 00 00 00
999.999 C2 09 63 63 5A
-999.999 3D 5A 00 00 0A
0.1 C0 0A 00 00
-0.1 3F 5A 00 00
0.00012345 BF 01 17 2D 00
-0.00012345 40 62 4C 37 00
1.2345678901234e-09 BC 0C 22 38 4E 5A 0C 22
-1.2345678901234e-09 43 57 41 2B 15 09 57 42
1.2345678901234e+09 C5 0C 22 38 4E 5A 0C 22
-1.2345678901234e+09 3A 57 41 2B 15 09 57 42
And so on.