为什么这两个golang整数转换函数会给出不同的结果?

时间:2014-07-11 22:01:24

标签: go int

我编写了一个将字节切片转换为整数的函数。

我创建的函数实际上是一个基于循环的实现 Rob Pike在这里发表了什么:

http://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html

这是Rob的代码:

i = (data[0]<<0) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);

我的第一个实现(在操场上的toInt2)并不起作用 我期望,因为它似乎将int值初始化为uint。 这看起来很奇怪,但它必须是特定于平台的,因为 go playground报告的结果与我的机器(mac)不同。

任何人都可以解释为什么这些函数在我的Mac上表现不同吗?

这是使用代码http://play.golang.org/p/FObvS3W4UD

指向游乐场的链接

这里是游乐场的代码(为方便起见):

/*

Output on my machine:

    amd64 darwin go1.3 input: [255 255 255 255]
    -1
    4294967295

Output on the go playground:

    amd64p32 nacl go1.3 input: [255 255 255 255]
    -1
    -1

*/

package main

import (
    "fmt"
    "runtime"
)

func main() {
    input := []byte{255, 255, 255, 255}
    fmt.Println(runtime.GOARCH, runtime.GOOS, runtime.Version(), "input:", input)
    fmt.Println(toInt(input))
    fmt.Println(toInt2(input))
}

func toInt(bytes []byte) int {
    var value int32 = 0 // initialized with int32

    for i, b := range bytes {
        value |= int32(b) << uint(i*8)
    }
    return int(value) // converted to int
}

func toInt2(bytes []byte) int {
    var value int = 0 // initialized with plain old int

    for i, b := range bytes {
        value |= int(b) << uint(i*8)
    }
    return value
}

2 个答案:

答案 0 :(得分:3)

这是一个有根据的猜测,但int类型可以是64位或32位,具体取决于平台,在我的系统上,而你的是64位,因为游乐场在nacl上运行,它是&#39; s 32bit。

如果您将第二个功能更改为全部使用uint,它将正常工作。

来自spec

uint     either 32 or 64 bits 
int      same size as uint
uintptr  an unsigned integer large enough to store the uninterpreted bits of a pointer value

答案 1 :(得分:1)

允许

int为32位或64位,具体取决于平台/实现。当它是64位时,它能够将2^32表示为有符号正整数,这就是您的机器上发生的情况。当它是32位(操场)时,它会像你期望的那样溢出。