如何找到映射至同一double的不同uint64_t值以验证JSON库问题
Great question! This is a classic floating-point precision issue, and it’s easy to produce concrete examples that will clearly show the problem to the project contributors.
Why the Collision Happens
Double-precision floating points (double) have 53 bits of significant precision (52 explicit bits plus one implicit leading 1). Any integer larger than (2^{53}) can’t be represented exactly as a double—there simply aren’t enough bits to capture every unique integer value beyond that threshold. Instead, multiple distinct integers get rounded to the same double value.
Concrete Example: Two Distinct uint64_t Values That Map to the Same Double
The simplest pair to demonstrate this is:
- (2^{53}) (which equals 9007199254740992)
- (2^{53} + 1) (which equals 9007199254740993)
These are completely distinct uint64_t values, but when converted to double, they become identical.
Verify with Code
You can quickly prove this with a simple Python snippet (Python’s float is equivalent to C++’s double):
# Define two distinct uint64_t values value1 = 2 ** 53 value2 = value1 + 1 # Print their raw integer values print(f"Integer 1: {value1}") print(f"Integer 2: {value2}") # Check if their double representations are equal print(f"Do their double representations match? {float(value1) == float(value2)}")
When you run this, the output will be:
Integer 1: 9007199254740992 Integer 2: 9007199254740993 Do their double representations match? True
Another Impactful Example
For a more dramatic demonstration, use larger values where the gap between representable doubles grows wider. For instance:
- (2^{54}) (18014398509481984)
- (2^{54} + 2) (18014398509481986)
These two distinct integers will also map to the same double value, since beyond (2^{54}), double can only represent even integers exactly—odd integers get rounded to the nearest even one.
How to Present This to Contributors
When opening an issue, include:
- A concise explanation of the 53-bit precision limit for
double. - The code snippet above to show the collision in action.
- A note that this bug means the library will incorrectly treat distinct large integers as equal during validation, which breaks use cases involving IDs, timestamps, or high-precision financial values.
内容的提问来源于stack exchange,提问作者Gillespie

