慕丝7291255
使用math.Float64bits()您可以使用math.Float64bits()which 返回一个与传递给它的uint64值具有相同字节/位的值float64。一旦有了uint64,对其执行按位运算就很简单了:f := 1.0 // Some float64 valuebits := math.Float64bits(f)if f >= 0 { bits ^= 0x8000000000000000} else { bits ^= 0xffffffffffffffff}然后序列化该bits值而不是ffloat64 值,就大功告成了。让我们看看实际效果。float64让我们创建一个包含数字及其字节的包装器类型:type num struct { f float64 data [8]byte}让我们创建这些 s 的一部分num:nums := []*num{ {f: 1.0}, {f: 2.0}, {f: 0.0}, {f: -1.0}, {f: -2.0}, {f: math.Pi},}序列化它们:for _, n := range nums { bits := math.Float64bits(n.f) if n.f >= 0 { bits ^= 0x8000000000000000 } else { bits ^= 0xffffffffffffffff } if err := binary.Write(bytes.NewBuffer(n.data[:0]), binary.BigEndian, bits); err != nil { panic(err) }}这就是我们如何按字节对它们进行排序:sort.Slice(nums, func(i int, j int) bool { ni, nj := nums[i], nums[j] for k := range ni.data { if bi, bj := ni.data[k], nj.data[k]; bi < bj { return true // We're certain it's less } else if bi > bj { return false // We're certain it's not less } // We have to check the next byte } return false // If we got this far, they are equal (=> not less)})现在让我们看看按字节排序后的顺序:fmt.Println("Final order byte-wise:")for _, n := range nums { fmt.Printf("% .7f %3v\n", n.f, n.data)}输出将是(在Go Playground上尝试):Final order byte-wise:-2.0000000 [ 63 255 255 255 255 255 255 255]-1.0000000 [ 64 15 255 255 255 255 255 255] 0.0000000 [128 0 0 0 0 0 0 0] 1.0000000 [191 240 0 0 0 0 0 0] 2.0000000 [192 0 0 0 0 0 0 0] 3.1415927 [192 9 33 251 84 68 45 24]没有math.Float64bits()另一种选择是先序列化float64值,然后对字节执行异或运算。如果数字是正数(或零),则第一个字节与 异或0x80,其余字节与 异或0x00,这基本上对它们什么都不做。如果数字是负数,则将所有字节与 异或0xff,这基本上是按位求反。实际上:唯一不同的部分是序列化和 XOR 操作:for _, n := range nums { if err := binary.Write(bytes.NewBuffer(n.data[:0]), binary.BigEndian, n.f); err != nil { panic(err) } if n.f >= 0 { n.data[0] ^= 0x80 } else { for i, b := range n.data { n.data[i] = ^b } }}其余的是一样的。输出也将相同。