Each non-empty cell is one record (see Records). Every cell record body starts the same way, then holds the value:
| Offset | Size | Field |
|---|---|---|
0 | 1 | Format byte |
1 | 2 | Column, from 0 (A) to 255 (IV) |
3 | 2 | Row, from 0 |
5 | … | The value, by record type |
The format byte
| Bits | Meaning |
|---|---|
| 7 | 1 protected, 0 unprotected. |
| 4–6 | Format type: 0 fixed, 1 scientific, 2 currency, 3 percent, 4 comma, 5 and 6 unused, 7 special. |
| 0–3 | For types 0 to 4, the number of decimal places (0 to 15). For type 7, the special format below. |
| Special code | Format |
|---|---|
| 0 | +/− (a bar chart of + or − signs) |
| 1 | General |
| 2 | Date: day-month-year |
| 3 | Date: day-month |
| 4 | Date: month-year |
| 5 | Text (show the formula) |
| 6 | Hidden (Symphony) |
| 7 | Date and time: hour-minute-second (Symphony) |
| 8 | Date and time: hour-minute (Symphony) |
| 9, 10 | Date: international formats (Symphony) |
| 11, 12 | Time: international formats 1 and 2 (Symphony) |
| 13, 14 | Unused |
| 15 | Default: use the window’s default format |
Examples from the Lotus document: 0x22 is currency with 2 decimal places,
unprotected; 0xF4 is month-year, protected. A cell with the default
format, unprotected, has 0x7F, and protected 0xFF.
Values
- INTEGER: a signed 16-bit integer, −32,767 to 32,767.
- NUMBER and the result in FORMULA: an 8-byte IEEE
754 double. Two special bit patterns stand for the error values: sign 1, exponent
all ones, fraction 0 is
NA(not available); sign 0, exponent all ones, fraction 0 isERR. In Symphony a non-zero fraction with sign 0 means the formula’s result is text, held in a following STRING record. - LABEL: zero-terminated text whose first character is the
alignment prefix:
'left,"right,^centred, or\repeat the text to fill the cell. - Dates are numbers of days, shown through the date formats.
Formulas
A FORMULA record body is the format byte, column and row, the result as a double
(offset 5), the formula’s length in bytes (offset 13, 2 bytes) and the formula
(offset 15). The formula is compiled into reverse Polish order: operands are pushed,
operators and functions take their arguments from the stack, and opcode 3 ends it.
A1+2*B1 is stored as A1, 2, B1, ×, +, return.
| Code | Meaning | Followed by |
|---|---|---|
0x00 | Constant | 8-byte double |
0x01 | Cell reference | Column (2) and row (2) |
0x02 | Range reference | Start column, start row, end column, end row (2 each) |
0x03 | End of formula | — |
0x04 | Parentheses (kept for display, ignored when calculating) | — |
0x05 | Integer constant | Signed 2-byte integer |
Operators
| Code | Operator | Precedence | Code | Operator | Precedence |
|---|---|---|---|---|---|
0x08 | − (negate) | 6 | 0x10 | <= | 3 |
0x09 | + | 4 | 0x11 | >= | 3 |
0x0A | − | 4 | 0x12 | < | 3 |
0x0B | × | 5 | 0x13 | > | 3 |
0x0C | ÷ | 5 | 0x14 | #AND# | 1 |
0x0D | ^ (power) | 7 | 0x15 | #OR# | 1 |
0x0E | = | 3 | 0x16 | #NOT# | 2 |
0x0F | <> | 3 | 0x17 | + (unary) | 6 |
Functions with fixed arguments
| Code | Function | Code | Function |
|---|---|---|---|
0x1F | @NA | 0x2F | @MOD(x, y) |
0x20 | @ERR | 0x30 | @CHOOSE(x, v0, …, vN) (variable count) |
0x21 | @ABS(x) | 0x31 | @ISNA(x) |
0x22 | @INT(x) | 0x32 | not defined |
0x23 | @SQRT(x) | 0x33 | @FALSE |
0x24 | @LOG(x) | 0x34 | @TRUE |
0x25 | @LN(x) | 0x35 | @RAND |
0x26 | @PI | 0x36 | @DATE(y, m, d) |
0x27 | @SIN(x) | 0x37 | @TODAY |
0x28 | @COS(x) | 0x38 | @PMT(principal, interest, term) |
0x29 | @TAN(x) | 0x39 | @PV(payment, interest, term) |
0x2A | @ATAN2(x, y) | 0x3A | @FV(payment, interest, term) |
0x2B | @ATAN(x) | 0x3B | @IF(condition, then, else) |
0x2C | @ASIN(x) | 0x3C | @DAY(x) |
0x2D | @ACOS(x) | 0x3D | @MONTH(x) |
0x2E | @EXP(x) | 0x3E | @ROUND(x, places) |
Functions with a list of arguments
These are followed by one byte giving how many arguments were pushed.
| Code | Function | Code | Function |
|---|---|---|---|
0x50 | @SUM | 0x59 | @IRR(guess, range) |
0x51 | @AVG | 0x5A | @HLOOKUP(x, range, offset) |
0x52 | @COUNT | 0x5B | @DSUM |
0x53 | @MIN | 0x5C | @DAVG |
0x54 | @MAX | 0x5D | @DCOUNT |
0x55 | @VLOOKUP(x, range, offset) | 0x5E | @DMIN |
0x56 | @NPV(interest, range) | 0x5F | @DMAX |
0x57 | @VAR | 0x60 | @DVAR |
0x58 | @STD | 0x61 | @DSTD |
The database functions 0x5B–0x61 take an input range,
an offset and a criteria range. Codes above 0x61, used by Release 2’s
additional functions, are not in the published document.
Example
A NUMBER record for cell B3 holding 1.5, currency with 2 decimals:
0E 00 0D 00 22 01 00 02 00 00 00 00 00 00 00 F8 3F
| Bytes | Meaning |
|---|---|
0E 00 0D 00 | Type 0x0E NUMBER, 13-byte body. |
22 | Unprotected, currency, 2 decimal places. |
01 00 02 00 | Column 1 (B), row 2 (the third row). |
00 … F8 3F | The double 1.5. |