learn-go-with-tests
learn-go-with-tests copied to clipboard
Floats should not be tested for equality using ==
https://github.com/quii/learn-go-with-tests/blob/2006553b99afb2bd5e1ef86b875d424883656336/structs/v8/shapes_test.go#L12
One should implement an approximately equal function
Can you explain your reasoning?
I'm not a Go expert, but it seems that doing an approximation would be the wrong approach. It's actually testing float to floats. It (shouldn't) need an approximation function.
I'm personally learning Go, so I'm probably ignorant of something important.
As a general rule: yes, floats should be compared with a tolerance. However, integers stored in float64 between -253 to 253 are precisely representable. Also the product of two such integers will be precisely represented if it is within that range. So for this specific test as for tests with integer values in that range no tolerance is needed. The test is fine, but if we were to use a table test with floating point values that have decimal values such as 0.1 ≠ float64(0.1) or the notorious (1.0 - 0.1 ≠ float64(0.9)) then we need tolerances.
Another reason that tolerances in tests with go are not an issue as with other languages is that go supports infinite precision floating point constants with a requirement that implementations at least have 256-bit accuracy in mantissa and 16-bits in exponent of representations. That minimum is extremely precise (My estimation is over 70 significant decimal digits). This means that if constants for tests are sufficiently precise for float64 no tolerances are needed. This of course only works if we know what the precise constant of the expected floating point value is.
In almost all cases we should really use an expectable tolerance value when comparing floating point values, unless:
- The expected constant value is exactly representable in the floating point type
- The test does not introduce a floating point error
Only in these two cases is it acceptable to use a comparison without tolerance
Could use this https://pkg.go.dev/github.com/google/go-cmp/cmp#example-Option-ApproximateFloats