skip to content

A nightly export writes a table to text and a reload comparison fails on a few decimal values — what happened, and what test catches this class?

level: seniorimportance: should knowfreq 48%

answer

  1. the file holds a printing, not the value
  2. how many digits did the writer print
  3. strict equality across printed text is fragile
  4. write it, read it straight back, compare

basics

~20 s

The file holds what the writer printed, not the value, so the reload re-parses a printed decimal. Whether that is lossless depends on how many digits the writer prints. Write, read straight back, and compare.

solid answer

~50 s

A text file stores characters, so a number leaves as a printed decimal and comes back as a parse of that printing. Whether anything was lost depends on the printed decimal width — how many digits the writer emits before the value stops being the value you had. Some writers print the fewest digits that read back as the identical value, in which case nothing is lost; others print a fixed number, and a fixed width chosen for legibility loses the rest for good. So establish which your write call does rather than assuming either. Two repairs: compare with a stated tolerance for anything that travelled as printed text, and reserve exact comparison for shapes that store the value itself. The test that catches the whole class is a deliberate round trip — write the table, read it straight back in the same job, and compare the two on the properties that can move.

go deeper

for a junior

Remember that a number written to a text file becomes the digits the writer printed, so what comes back is a parse of that printing rather than the value you had.

for a middle

Explain why this varies: some writers print the fewest digits that read back identical and lose nothing, while a fixed printed width discards the rest permanently. Name which one you are relying on.

for a senior

Diagnose from the shape of the failure, replace exact comparison with a stated tolerance where values crossed printed text, and add the write-then-read-back comparison so the next option change fails loudly.

for a principal

The call is where fidelity is guaranteed at all: whether handoffs between jobs are allowed to be text, what a team pays for legible files, and who owns the check that keeps a formatting choice from becoming a data change.

## Where the digits went **Re-parsed delimited text** stores characters. A number in memory has a stored representation of a fixed width; in the file it is a sequence of digits that **the writer** — the call that turns a table back into bytes — chose to print. On the way back, **the reader** parses that sequence. Nothing carried the original value across; what crossed was a printing of it. So the question is never "does text lose precision". It is **how many digits did the writer print**, and that is a property of the write call in use, not of text as a shape. ## This one genuinely varies, so establish it rather than assume it Two behaviours are both common and they lead to opposite conclusions: - **Print the fewest digits that read back as the identical value.** Under this rule the round trip is exact for those numbers: the printed text re-parses to the same stored value, bit for bit. Nothing is lost and a strict comparison passes. - **Print a fixed number of digits.** Under this rule everything beyond that width is gone the moment the line is written, and no declaration, no reader setting and no later step can bring it back. The second is what you get whenever somebody sets a decimal width for legibility, and it is the usual cause of "it was fine last quarter". A handful of rows failing rather than all of them is itself a clue: it points at values whose exact representation needed more digits than the width allowed, not at a systematic transformation. A **self-describing binary columnar file** — values stored column by column in their declared types, with the declaration written into the file itself — sidesteps the whole question, because it stores the value rather than a rendering of it. ## Exact equality is the wrong check on a text handoff Even where the writer prints faithfully today, an exact comparison across a text handoff is a check that depends on a formatting decision nobody thinks of as load-bearing. Somebody sets a width for a report, or a different job re-writes the file, and the comparison starts failing on values that are, for every purpose the business has, the same number. | check | right when | wrong when | |---|---|---| | strict equality | the shape stores the value itself | anything travelled as printed decimal text | | equality within a stated tolerance | values crossed a printed representation | the field is an identifier or a code, where near-enough is meaningless | | comparing the printed text | you are auditing the file's own content | you are asking whether the numbers agree | State the tolerance in the job rather than leaving it to whoever wrote the check, so that a later change to the printed width fails visibly instead of being absorbed. ## The test: read, write, read The general form of this defect is that **a handoff loses something and nobody looks until a consumer complains**. The test is cheap and almost nobody runs it. Take the table you already have in memory, write it with the exact call and options production uses, read it straight back with the exact call and options the consumer uses, and compare the two tables. This is one table and one shape, with no change of logic in between — the only variable is the trip. Compare them on the properties that can actually move: 1. **The column types.** Did every column come back as the representation it left as, or did something arrive as characters? 2. **The table's row labels**, in tools that have them. Are they still the identity, or are they now a column? 3. **The absent markers.** Are the cells that had no value still empty, in the same places, or did some of them come back as ordinary text? 4. **Any declared list of permitted values.** Is it the list you declared, or the values this extract happened to contain? 5. **The numbers**, within a stated tolerance, and exactly where the shape claims to store the value itself. What comes out is not a pass or a fail so much as an inventory: *this shape, with these options, carries these four things and drops that one.* Then you decide which losses you accept. ## Where the test lives Run once by hand when the format was chosen, it proves nothing about the day somebody changes a write option. Put it where a change has to walk past it: in the test suite that guards the export, or in the job itself against a small fixed sample on every run. The cost is one extra write and read of a few rows. The alternative is finding out from a consumer who has already published the number.

  • If the writer prints the fewest digits that read back identical, is the trip lossless?
    For those numbers, yes — the printed text re-parses to the same stored value. It stops being true the moment anyone sets a fixed decimal width for legibility, or a later step re-writes the file with different options. It is a property of the write call in use, not of text.
  • What should the comparison use instead of exact equality?
    Equality within a stated tolerance for anything that travelled as a printed decimal, and exact comparison only where the shape stores the value itself. Identifiers and codes are the exception: near-enough is meaningless there, so they should never have been written in a way that can shift.
  • Why compare the whole table rather than just the numbers?
    Because the digits are one of several things a trip can move. The types, the row labels, the absent markers and any declared list of permitted values travel through the same file and fail just as quietly, and you get all of them from the same one-minute round trip.
  • Where should the round-trip check live so it is not skipped?
    Where a change has to pass it: in the suite that guards the export, or in the job itself against a small fixed sample on every run. A check performed once when the format was chosen says nothing about the day somebody edits a write option.

saying these in an interview costs you the question

  • Says text always loses the last digits of a number.
  • Blames the reader for rounding values on the way in.
  • Compares values exactly after a printed-decimal handoff.
  • Fixes the failing rows instead of establishing the write's printing rule.
  • Runs a round-trip check once by hand and never again.