-
Type:
Improvement
-
Resolution: Done
-
Priority:
Minor - P4
-
None
-
Affects Version/s: 1.4.7, 1.5.1, 1.5.2, 1.5.3
-
Component/s: BSON
-
None
-
Environment:Windows
Alpine Linux/Docker Containers
Go 1.16.5
-
None
-
None
-
None
-
None
-
None
-
None
-
None
Motivation
If attempting to unmarshal a float64 into a float32 results in truncation, and the destination does not have the truncate tag, the error errCannotTruncate is returned. This error consists of the message "float64 can only be truncated to an integer type when truncation is enabled". The error message is misleading. A float64 can be unmarshaled into a float32 if the truncate tag is present.
Scope
Update the error message to apply to this case. Consider changing to the following: "float64 can only be truncated when the truncate tag is present"
Original ticket description
We've run across an issue where the truncation logic in the BSON lib is causing an issue due to a floating point rounding error when trying to validate a float32 value when comparing float64(float32(f)) to the mongo returned float64(f).
Here's the minimum reproducible showcasing that 0.1 returns incorrectly: https://play.golang.org/p/eYANaXFKVk9
package main import ( "fmt" ) func main() { a := float64(0.1) // What type is coming back from mongo b := float32(a) // What type is being conformed based on specified type in struct c := float64(b) // The conversion back, which causes the rounding point error going from f32 -> f64 fmt.Printf("%#+v | %#+v | %#+v\n", a, b, c) fmt.Printf("not equal? %t\n", float64(float32(a)) != a) }
Returns:
0.1 | 0.1 | 0.10000000149011612
not equal? true
This is occurring here: https://github.com/mongodb/mongo-go-driver/blob/49af6e279ffe534210dca95e375d372517145e44/bson/bsoncodec/default_value_decoders.go#L480