为了账号安全,请及时绑定邮箱和手机立即绑定

Go 代码在本地环境中的运行结果与在 go play 中运行的结果不同

Go 代码在本地环境中的运行结果与在 go play 中运行的结果不同

Go
四季花海 2022-05-18 15:41:19
我正在使用Go实现如下所述的算法:有一个数组,一个数字只出现一次,其他所有数字都出现3次,找到这个数字只出现一次我的代码如下:import (    "testing")func findBySum(arr []int) int {    result := 0    sum := [32]int{}    for i := 0; i < 32; i++ {        for _, v := range arr {            sum[i] += (v >> uint(i)) & 0x1        }        sum[i] %= 3        sum[i] <<= uint(i)        result |= sum[i]    }    return result}func TestThree(t *testing.T) {    // except one nubmer,all other number appear three times    a1 := []int{11, 222, 444, 444, 222, 11, 11, 17, -123, 222, -123, 444, -123}  // unqiue number is 17    a2 := []int{11, 222, 444, 444, 222, 11, 11, -17, -123, 222, -123, 444, -123} // unque number is -17    t.Log(findBySum(a1))    t.Log(findBySum(a2))}但是,我发现我的PC上的运行结果是错误的,而在https://play.golang.org/p/hEseLZVL617中运行的相同代码是正确的,我不知道为什么。结果在我的电脑上:结果https://play.golang.org/p/hEseLZVL617:如我们所见,当唯一编号为正时,两个结果都是正确的,但是当唯一编号为负时,我的PC中的结果是错误的,而在线结果是正确的。我认为这与我的代码中的位操作有关,但我找不到根本原因。我使用了 IDEA 2019.1.1 和下面列出的 Golang 版本:我不知道为什么相同的代码可以在网上正常工作,而不能在我的本地电脑上工作,谁能帮我分析一下?提前致谢!
查看完整描述

1 回答

?
喵喵时光机

TA贡献1846条经验 获得超7个赞

大小int取决于平台,可能是 32 位,也可能是 64 位。在 Go Playground 上它是 32 位的,在您的本地机器上它是 64 位的。


如果我们将您的示例更改为int64显式使用而不是int,则结果在Go Playground上也是相同的:


func findBySum(arr []int64) int64 {


    result := int64(0)

    sum := [32]int64{}


    for i := int64(0); i < 32; i++ {

        for _, v := range arr {

            sum[i] += (v >> uint64(i)) & 0x1

        }

        sum[i] %= 3

        sum[i] <<= uint(i)

        result |= sum[i]

    }


    return result

}


func TestThree(t *testing.T) {

    // except one nubmer,all other number appear three times

    a1 := []int64{11, 222, 444, 444, 222, 11, 11, 17, -123, 222, -123, 444, -123}  // unqiue number is 17

    a2 := []int64{11, 222, 444, 444, 222, 11, 11, -17, -123, 222, -123, 444, -123} // unque number is -17

    t.Log(findBySum(a1))

    t.Log(findBySum(a2))

}

您执行假定 32 位整数大小的按位运算。要在本地获得正确的结果(您的体系结构以及 and 的大小int)uint,请将64-bit所有ints更改为int32and :uintuint32


func findBySum(arr []int32) int32 {


    result := int32(0)

    sum := [32]int32{}


    for i := int32(0); i < 32; i++ {

        for _, v := range arr {

            sum[i] += (v >> uint32(i)) & 0x1

        }

        sum[i] %= 3

        sum[i] <<= uint(i)

        result |= sum[i]

    }


    return result

}


func TestThree(t *testing.T) {

    // except one nubmer,all other number appear three times

    a1 := []int32{11, 222, 444, 444, 222, 11, 11, 17, -123, 222, -123, 444, -123}  // unqiue number is 17

    a2 := []int32{11, 222, 444, 444, 222, 11, 11, -17, -123, 222, -123, 444, -123} // unque number is -17

    t.Log(findBySum(a1))

    t.Log(findBySum(a2))

}

教训:如果您执行的计算结果取决于表示大小,请始终保持明确,并使用固定大小的数字,如int32、int64、uint32、uint64。


查看完整回答
反对 回复 2022-05-18
  • 1 回答
  • 0 关注
  • 162 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信