Fix 1.23E+15: why Excel ruins long IDs, and how to stop it
You open an export and a column of order identifiers reads
1.23457E+15. The first
question is not how to make it display properly. The first question is whether the
digits still exist.
Because sometimes they do and sometimes they do not, and the difference decides whether you have a formatting annoyance or a data recovery problem.
The 15 significant digit ceiling
Excel stores every number as an IEEE 754 double precision float. A double holds roughly 15 to 17 significant decimal digits, and Excel deliberately limits both storage and display to 15 significant digits so that floating point artifacts never surface in a spreadsheet.
The consequence is precise and easy to reproduce. Type
1234567890123456,
which is sixteen digits, into a cell and press Enter. The cell now contains
1234567890123450. The
sixth digit from the right became a zero. Not hidden, replaced.
This is why damaged files have a signature. Look down a column of long identifiers. If
a suspicious number of them end in
0, and the ones that
do are all sixteen digits or longer, they have been through a spreadsheet. Real
identifiers from a sequence or a hash do not cluster on a trailing zero.
Symptom: is this display or is this damage?
Cause. Two different things produce the same on-screen appearance, and Excel tells you nothing about which one happened.
Test. Select the cell and set the number format to Number with zero decimal places, or just widen the column. Scientific notation is a display format and it gives way immediately.
- All digits reappear, matching the source. Display only. The value is intact and you have a cosmetic problem.
- Digits reappear but the tail is zeros that are not in the source file. Rounding. The original digits are gone from this workbook.
The comparison against the source file is the part people skip. Without it you cannot distinguish a value that legitimately ends in zeros from one that was flattened. Open the CSV in a viewer that does not reformat, put the two side by side, and look at ten rows.
Fix it: open the source CSV and compare the digits →
Fix: import the column as text
If the source file is intact, the fix is to stop the number conversion from happening. An identifier is not a quantity; nobody computes the average of two order IDs.
In Excel, Data, then From Text/CSV, then Transform Data, then set the column type to Text before loading. Not after. Setting it to Text after the value has been parsed leaves you with the text of the already-rounded number, which is the worst of both worlds: it looks deliberate and it is still wrong.
In Google Sheets, File, then Import, with Convert text to numbers set to No.
In Python:
df = pd.read_csv("orders.csv", dtype={"order_id": str, "device_imei": str})
Fix it: load the CSV and pin the column type before anything else runs →
Fix: keep identifiers as strings end to end
The durable fix is upstream. If a column is an identifier, make it a string everywhere: in the database schema, in the export, in the CSV, in the workbook, in the API response. Every hop that treats it as a number is a chance to lose precision, and precision loss is not reversible.
This has practical teeth in a browser too. JavaScript's
Number is the same
IEEE 754 double, so any web tool that parses a 19-digit identifier into a number breaks
it identically. We hit this in our own grid: DuckDB returns
SUM(int_col) as a
HUGEINT, and Apache Arrow hands it over as a big-number object rather than a JavaScript
number. Converting it eagerly would round it.
So the rule in our value renderer is explicit: a value that outruns
Number.isSafeInteger
stays a string all the way to the cell rather than silently rounding. It is one
conditional, and it is the difference between a correct grid and a plausible one.
Fix it: store the file as Parquet, where the column's type is part of the file →
Which identifiers are actually at risk
It is worth knowing which columns to worry about, because the fix costs a little effort and applying it to everything is not free. The threshold is 16 significant digits. Below that, a spreadsheet round trip is safe.
| Identifier | Typical digits | Safe in a spreadsheet? |
|---|---|---|
| EAN-13 barcode | 13 | Yes, but leading zeros still vanish |
| Payment card number | 15 to 16 | Borderline; 16 rounds |
| IMEI | 15 | At the edge, treat as text |
| Snowflake-style ID | 18 to 19 | No, always corrupted |
| Concatenated composite key | Varies, often 17+ | No |
| UUID (with hyphens) | Not numeric | Safe, never parsed as a number |
That last row is a genuine argument for UUIDs over big integer keys when data will pass through spreadsheets. A value containing hyphens and letters is never mistaken for a quantity, so it survives tools that were never designed to protect it.
Check what is really in the file
Three checks, in order, and you will know exactly where you stand.
- Look at the raw file.
head -5 file.csv. Full-length digits mean the CSV is fine and the problem is the import. - Count the digits. Under 16 significant digits, you are safe in a spreadsheet. At 16 and above, treat the column as text and never let it be a number.
- Look for the trailing-zero signature. A column where many long values end in zero has already been through a spreadsheet, and the source system is the only place the real values still exist.
If step three comes back positive, say so early. Recovering identifiers from an upstream system on day one is routine; discovering the problem after three weeks of downstream joins is a project.
Fix it: profile the file and find the columns whose values run long →