Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

math.Signbit(-float64(0)) is false #2196

Closed
gopherbot opened this issue Aug 28, 2011 · 7 comments
Closed

math.Signbit(-float64(0)) is false #2196

gopherbot opened this issue Aug 28, 2011 · 7 comments

Comments

@gopherbot
Copy link

by mikesamuel:

What steps will reproduce the problem?
1. In the Go playground enter the below and hit COMPILE & RUN

package main

import (
    "fmt"
    "math"
    )

func main() {
    fmt.Println(math.Copysign(0, -1))
}

2. See "-0" printed as expected
3. In the Go playground enter the below and hit COMPILE & RUN

package main

import "fmt"

func main() {
    z := float64(0)
    nz := -z
    fmt.Println(nz)
}
4. See "-0" printed
5. In the Go playground enter the below and hit COMPILE & RUN

package main

import "fmt"

func main() {
    nz := -float64(0)
    fmt.Println(nz)
}
6. See "0" printed

What is the expected output?

I expect all 3 programs to print "-0".


What do you see instead?

The first 2 print "-0" but the third prints "0".


Which compiler are you using (5g, 6g, 8g, gccgo)?

I tested using the playground, but can repeat this behavior on 6g.


Which operating system are you using?

Mac OS


Which revision are you using?  (hg identify)

5e1053337103+ tip
@gopherbot
Copy link
Author

Comment 1 by mikesamuel:

A shorter test.  The below run in the playground prints "false, true", but I expect it
to print "true, true".
package main
import (
    "fmt"
    "math"
)
func main() {
        z := float64(0)
    nz := -z
    fmt.Printf("%t, %t\n", math.Signbit(-float64(0)), math.Signbit(nz))
}

@rsc
Copy link
Contributor

rsc commented Aug 29, 2011

Comment 2:

What you are seeing is a mismatch between the
run time behavior of floating point numbers and
the ideal constant evaluation in the Go compiler.
They're different: the constants in Go are just that:
constants.  There's no infinity, no NaN, no negative zero.
Those are all IEEE754 concepts, so they exist at
run time, but not in the compiler.  If you want an
IEEE754 negative zero, you can be explicit by
using math.Copysign.
Russ

@rsc
Copy link
Contributor

rsc commented Aug 29, 2011

Comment 3:

Owner changed to @rsc.

Status changed to WorkingAsIntended.

@gopherbot
Copy link
Author

Comment 4 by mikesamuel:

From the language spec ( http://golang.org/doc/go_spec.html#Conversions )
"Converting a constant yields a typed constant as result."
"     float32(2.718281828)     // 2.718281828 of type float32"
"The values of typed constants must always be accurately representable as values of the
constant type."
so I expect float64(0) is not an ideal constant, but is a typed constant of type
float64, and the negation operator applied to that should behave as advertised in
"For floating-point numbers, +x is the same as x, while -x is the negation of x."

@gopherbot
Copy link
Author

Comment 5 by mikesamuel:

Your argument makes sense for float64(-0), but I don't see how it applies to -float64(0).

@gopherbot
Copy link
Author

Comment 6 by asaz989:

Do you mean the other way around? float64(-0) is a conversion of the ideal constant -0
to float64, which seems like it should discard the sign bit, while -float64(0) should
apply the negation to a (non-ideal) typed constant, and so keep the sign bit.

@gopherbot
Copy link
Author

CL https://golang.org/cl/14261 mentions this issue.

gopherbot pushed a commit that referenced this issue Sep 10, 2015
This matches existing behavior, see issue #2196

Change-Id: Ifa9359b7c821115389f337a57de355c5ec23be8f
Reviewed-on: https://go-review.googlesource.com/14261
Reviewed-by: Keith Randall <khr@golang.org>
@golang golang locked and limited conversation to collaborators Sep 8, 2016
@rsc rsc removed their assignment Jun 22, 2022
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants