JSON pitfalls: money, big ids and dates

API design: REST, HTTP, GraphQL and gRPC Junior Python 3.13+ PostgreSQL 17+ Reviewed By Best Latest Apps

Predict the output

What does this print?

Python 3.13
from decimal import Decimal

print(0.1 + 0.2 == 0.3)
print(Decimal("0.1") + Decimal("0.2") == Decimal("0.3"))
print(float(2**53 + 1) == 2**53 + 1)

Options
Hint 1 of 1

What's the largest exact integer in a double?

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A False, True, False

Correct. Binary floats miss 0.3, Decimal is exact, and 2^53 + 1 can't be held in a double.

Binary floats can't store 0.1 or 0.2 exactly, so their sum misses 0.3. Decimal from strings does exact decimal arithmetic, and a double has 53 bits of precision, so 2^53 + 1 rounds to 2^53.

Why not the others?
  • B True, True, True. Floats can't represent 0.1 exactly.
  • C False, True, True. 2^53 + 1 rounds to 2^53 as a float.
  • D False, False, False. Decimal built from strings is exact.

30-second answer

JSON numbers are often parsed as 64-bit floats. JavaScript can't represent integers above 2^53 − 1 exactly, so large ids get silently rounded; send them as strings. Floats can't hold most decimal fractions exactly, so send money as integer minor units or a decimal string plus a currency code. Send timestamps as RFC 3339 strings in UTC with an explicit offset, not local times or ambiguous formats.

Practise saying it · 30 s. No recording, just a timer

What goes wrong with JSON numbers?

Say your answer out loud, then check which of these points you covered:

  • Floats for money
  • Ids above 2^53
  • Strings for ids
  • Minor units or decimal strings
  • RFC 3339 UTC

Deep dive

0.1 + 0.2 != 0.3 in binary floating point.

Twitter-style snowflake ids exceed 2^53; that's why some APIs ship an id_str field.

Dates without a zone are ambiguous; durations as ISO 8601 (PT30S) or plain seconds.

Use Decimal in Python for money arithmetic.

Common mistakes

  • Prices as floats.
  • 64-bit ids as numbers to browser clients.
  • Timestamps in server local time.

Senior take & follow-ups

Hit the three traps: floats for money, big integers, and time zones.

Follow-up questions

Think of your answer first, then open the hint.

  1. How does Python's json handle Decimal?

    Show hint

    It doesn't by default; serialize to string or pass default=str.

  2. Why strings for ids?

    Show hint

    Clients never do arithmetic on ids, and strings survive every parser.

Suggest a fix if something here is wrong or out of date.