|
Adding more detail about why we decided to close this:
Conversion between numeric types can be silently lossy in non-intuitive ways, so we should limit the ability to silently lose data in the As* APIs. Specifically, the following BSON numeric type conversion cases are lossy:
- Converting a BSON "double" (64-bit float) into a Go int32 will silently lose data for values:
- Any value with a fractional part (truncates the fractional part)
- Greater than math.MaxInt32 (returns math.MinInt32)
- Less than math.MinInt32 (returns math.MinInt32)
- NaN, +Inf, -Inf (returns math.MinInt32)
- Converting a BSON "double" (64-bit float) into a Go int64 will silently lose data for values:
- Any value with a fractional part (truncates the fractional part)
- Greater than math.MaxInt64 (returns math.MinInt64)
- Less than math.MinInt64 (returns math.MinInt64)
- NaN, +Inf, -Inf
- Converting a BSON "int64" (64-bit integer) into a Go int32 will silently lose data for values:
- Greater than math.MaxInt32 (overflow and flip sign)
- Less than math.MinInt32 (overflow and flip sign)
- Converting a BSON "int64" (64-bit integer) into a Go float64 will silently lose data for values:
- Greater than 2^53 (lose integer precision)
- Less than -1 * 2^53 (lose integer precision)
Converting BSON "decimal128" to native Go types is even less intuitive and should be avoided.
Since we know the cases where we'll lose data, it's possible we can allow conversion when it isn't lossy (which is true for many every-day values). For reference, bson.Unmarshall does allow converting between int <-> float when there is no truncation, but does not catch precision errors for too-large integer values.
|