【问题标题】:Distinguishing sign of zero : -float64(0) from float64(0) in Go区分零的符号:-float64(0) 与 Go 中的 float64(0)
【发布时间】:2011-08-29 07:57:04
【问题描述】:

我想以不丢失符号信息的方式序列化浮点。具体来说,我想区分 IEEE-754 负零和常规零。

language spec

浮点除以零的结果没有超出 IEEE-754 标准;是否发生运行时恐慌是特定于实现的。

这表明我做不到

n == 0 && (float64(1) / n) < 0

我试过 math.Copysignmath.Signbit

func Signbit(x float64) bool

如果 x 为负数或负零,Signbit 返回 true

但是

n == 0 && math.Signbit(n)

似乎不适合

n := -float64(0)

有什么想法吗?

编辑:

我提交了issue 2196 以跟踪我认为两者之间令人困惑的区别

nz := -float64(0)

pz := float64(0)
nz := -pz

按照 peterSO 的建议。

【问题讨论】:

    标签: go ieee-754 zero


    【解决方案1】:
    package main
    
    import (
        "fmt"
        "math"
    )
    
    func main() {
        pz := float64(0)
        nz := -pz
        fmt.Println(pz, math.Signbit(pz), nz, math.Signbit(nz))
        if n := nz; n == 0 && math.Signbit(n) {
            fmt.Println("n is negative zero:", n)
        }
    }
    

    输出:

    0 false -0 true
    n is negative zero: -0
    

    【讨论】:

    • 谢谢,我想我明白了。 -float64(0) 中的符号会丢失,但在您执行显式额外操作时不会丢失。
    【解决方案2】:

    我无法让 go playground (http://golang.org/doc/play/) 通过在源代码中直接输入来生成 -0;我推测编译器会将其转换为 0。

    但是,我可以像这样生成 -0:

    fmt.Println(0);
    fmt.Println(-0);
    hmm := -1 / math.Inf(1);
    fmt.Println(math.Signbit(hmm));
    fmt.Println(hmm);
    

    打印:

    0
    0
    true
    -0
    

    【讨论】:

    • 有人可能想知道,针对 atan2 的单元测试是否真的按照作者的预期工作?
    • 啊,所以我的测试未能正确生成真正的 -0 值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-22
    • 1970-01-01
    • 1970-01-01
    • 2020-08-06
    • 2016-01-29
    • 2012-10-04
    相关资源
    最近更新 更多