|
|
Created:
11 years, 4 months ago by iant Modified:
11 years, 4 months ago Reviewers:
CC:
golang-dev, remyoudompheng, rsc Visibility:
Public. |
Descriptiontest: add test for floating point rounding of constants
Failed with gccgo.
Patch Set 1 #Patch Set 2 : diff -r 9764a39320d8 https://go.googlecode.com/hg/ #
Total comments: 3
Patch Set 3 : diff -r b5f58df8efce https://go.googlecode.com/hg/ #MessagesTotal messages: 10
Hello golang-dev@googlegroups.com, I'd like you to review this change to https://go.googlecode.com/hg/
Sign in to reply to this message.
Is this specified anywhere? http://golang.org/ref/spec#Constant_expressions says: "A compiler may use rounding while computing untyped floating-point or complex constant expressions; see the implementation restriction in the section on constants." But it never says that typing a floating-point constant should change its value (which itself is rounded but not at float32/float64 precision).
Sign in to reply to this message.
The spec says: "That said, every implementation must: Represent floating-point constants, including the parts of a complex constant, with a mantissa of at least 256 bits and a signed exponent of at least 32 bits." It suggests that: const x = 1 - float64(1.00000000000000000001) const x = float64(1 - 1.00000000000000000001) should be equivalent expressions. The playground says the first one is zero and the second one isn't.
Sign in to reply to this message.
On 2012/11/16 07:01:32, remyoudompheng wrote: > Is this specified anywhere? > > http://golang.org/ref/spec#Constant_expressions says: > > "A compiler may use rounding while computing untyped floating-point or complex > constant expressions; see the implementation restriction in the section on > constants." > > But it never says that typing a floating-point constant should change its value > (which itself is rounded but not at float32/float64 precision). The spec says "Converting a constant yields a typed constant as result." So it seems to me that after that point the rules about untyped constants no longer apply. Though that also seems to be the only place in the spec where the phrase "typed constant" appears, so certainly matters are not as clear as possible. Intuitively, what should float64(float32(0.01)) mean? It seems peculiar to say that it should mean the same thing as float64(0.01). And with the "typed constant" statement the spec seems to support the idea that float64(float32(0.01)) != float64(0.01). And that is what the gc compiler implements. So while the spec can probably be clarified, I'm reasonably comfortable with the test case.
Sign in to reply to this message.
On 2012/11/16 07:08:21, remyoudompheng wrote: > The spec says: "That said, every implementation must: Represent floating-point > constants, including the parts of a complex constant, with a mantissa of at > least 256 bits and a signed exponent of at least 32 bits." > > It suggests that: > > const x = 1 - float64(1.00000000000000000001) > const x = float64(1 - 1.00000000000000000001) > > should be equivalent expressions. The playground says the first one is zero and > the second one isn't. Well, with the "typed constant" reading, that seems correct. float64(1.00000000000000000001) is a typed constant. But I just now spotted another use of "typed constant" in the spec, and it suggests that this program should be invalid. The spec says "The values of <i>typed</i> constants must always be accurately representable as values of the constant type." The value 1.00000000000000000001 can not be represented as a float64. So perhaps the compiler should reject this program.
Sign in to reply to this message.
Sign in to reply to this message.
On 2012/11/16 14:22:20, iant wrote: > But I just now spotted another use of "typed constant" in the spec, and it > suggests that this program should be invalid. The spec says "The values of > <i>typed</i> constants must always be accurately representable as values of the > constant type." The value 1.00000000000000000001 can not be represented as a > float64. So perhaps the compiler should reject this program. But 0.1 cannot be either accurately represented as a float64. Why would the implicit rounding of 0.1 be acceptable but not the rounding of 1.000000000000000000001 ? What about float64(3.1415926535897932384626433)?
Sign in to reply to this message.
On 2012/11/16 15:06:06, remyoudompheng wrote: > On 2012/11/16 14:22:20, iant wrote: > > But I just now spotted another use of "typed constant" in the spec, and it > > suggests that this program should be invalid. The spec says "The values of > > <i>typed</i> constants must always be accurately representable as values of > the > > constant type." The value 1.00000000000000000001 can not be represented as a > > float64. So perhaps the compiler should reject this program. > > But 0.1 cannot be either accurately represented as a float64. Why would the > implicit rounding of 0.1 be acceptable but not the rounding of > 1.000000000000000000001 ? What about float64(3.1415926535897932384626433)? Yeah, we should change the spec. That's the issue I filed.
Sign in to reply to this message.
LGTM The part about "is 0.01" is not precisely correct. The numbers below are the real ones. It doesn't matter because in a Go program 0.01 used in a float64 context really means 0.01000000000000000020816681711721685132943093776702880859375, but it will avoid confusion later if we are precise here. Also, although I didn't note it below, I think it might help to use panic(fmt.Sprintf("F=%.1000g, want %.1000g", F, F32)) because the default printer for float64s is not very precise and perhaps not even very accurate. https://codereview.appspot.com/6855053/diff/10001/test/fixedbugs/bug470.go File test/fixedbugs/bug470.go (right): https://codereview.appspot.com/6855053/diff/10001/test/fixedbugs/bug470.go#ne... test/fixedbugs/bug470.go:11: var F = float64(float32(0.01)) var F = float64(float32(0.01)) const ( F32 = 0.00999999977648258209228515625 F64 = 0.01000000000000000020816681711721685132943093776702880859375 ) https://codereview.appspot.com/6855053/diff/10001/test/fixedbugs/bug470.go#ne... test/fixedbugs/bug470.go:14: // 0.01 rounded to float32 then to float64 is 0.009999999776482582. is F32. next line is F64. https://codereview.appspot.com/6855053/diff/10001/test/fixedbugs/bug470.go#ne... test/fixedbugs/bug470.go:16: if F == 0.01 { if F != F32 { panic(F) }
Sign in to reply to this message.
*** Submitted as http://code.google.com/p/go/source/detail?r=b26a08dc81f0 *** test: add test for floating point rounding of constants Failed with gccgo. R=golang-dev, remyoudompheng, rsc CC=golang-dev http://codereview.appspot.com/6855053
Sign in to reply to this message.
|