Open nsajko opened 3 years ago
This all depends on the phrase
the next representable float64 value
I would interpret the next representable value after -0 to be 4.941e-324, not 0. 0 is not "after" -0 in my mind, as 0 == -0. I can certainly see how that might be confusing, though.
We could add additional special cases to the docs, if you think that would help. Or was there something else you had in mind?
I see these options:
I vote for 1. We don't want to violate the Go 1 compatibility guarantee. I guess you could argue that this fits under the "bugs" exception, but it is not clear to me that it is even a bug. I think we'd need a stronger argument to make a backwards-incompatible change.
/cc @griesemer @rsc
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Some explanations are in the comments: https://play.golang.org/p/vaQBl7C6FNm
What did you expect to see?
What did you see instead?
Other notes
Relevant observation: negative and positive floating point zeros are distinct values in Go, but compare equal with the
==
operator. This is OK, but could be considered as the cause of the bug in the implementation.Inconsistency with other finite float64 arguments
The inconsistency with the handling of zero arguments causes unexpected behavior when looping using the Nextafter functions.
This is not an actual issue for me, but it seems like it might be for someone who uses Nextafter: assuming a nonzero negative number
x
is chosen, start iterating on it like this:x = math.Nextafter32(x, 0)
, with the aim of breaking the loop at zero (a similar situation is observed when starting from a positive value, instead of a negative one). The loop, unexpectedly, will never exit in some cases: https://play.golang.org/p/eWs0pg8SXriInconsistency with C
Even though at first I thought that this is a relatively straightforward issue (because of the "next representable float64 value" explicit wording), this actually seems to be a tricky issue if compared with C, and it's even possible you may want to consider this a documentation bug instead of a behavioral bug, along with a couple other options.
The C nextafter functions were supposedly the inspiration for the Go version so it might be relevant to compare to them, also, it might be desirable to be compatible with them if you're appropriating their names already.
Both C17 and the current C draft have this to say about nextafter:
Notice the
return y if x equals y
explicit requirement about zeros - this is where C differs from Go currently.But, except for that, the C implementations are actually like Go: they don't follow the spec when x is negative zero and y is a positive nonzero value, or when x is positive zero and y is a negative nonzero value. (In that case the other zero is "skipped over".)
C program for comparison (give it "0" on its stdin):
Outputs: