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

Go 使用比位运算符返回除 java 脚本以外的其他总和

Go 使用比位运算符返回除 java 脚本以外的其他总和

Go
绝地无双 2022-09-26 17:27:19
我试图使用Go在JS中制作函数端口,但我遇到了奇怪的问题。函数的目标是对字符串中每个字母的 ascii 代码求和。一切都很好,直到字符串长度<= 6之后,Go返回其他结果。原件来自 JSfunction c(e) { // e is string    var t = 0;     if (!e) // if e == ""       return t;     for (var n = 0; n < e.length; n++) {            t = (t << 5) - t + e.charCodeAt(n),            t &= t     }     return t}sdc("Google") // returns 2138589785c("Google1") // returns 1871773944戈伊港package mainimport (    "fmt")func main() {    fmt.Println(CountChars("Google")) // returns 2138589785    fmt.Println(CountChars("Google1")) // returns 66296283384}func CharCodeAt(s string) int {    return int([]rune(s)[0])}func CountChars(char string) int {    var sum int = 0    if char == "" {        return sum    }    for x:=0; x<len(char); x++ {        charToCode := string(char[x])        sum = (sum << 5) - sum + CharCodeAt(charToCode)        sum &= sum    }    return sum}去游乐场游戏代码中的 JS 游乐场
查看完整描述

2 回答

?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

Javascript 中的整数是 32 位的,而 Go 的整数取决于体系结构,可能是 32 位和 64 位。它是 Go 游乐场上的 64 位。由于每次迭代向左移动 5,因此使用超过 6 个字符肯定会在 Javascript 中“溢出”(但在 Go 中尚未溢出):。int7*5=35 > 32 bits


使用显式 32 位整数 () 来获得与 Javascript 中相同的输出:int32


func CountChars(char string) int32 {

    var sum int32 = 0

    if char == "" {

        return sum

    }

    for x := 0; x < len(char); x++ {

        sum = (sum << 5) - sum + int32(char[x])

        sum &= sum

    }

    return sum

}

这种方式的输出将与Javascript的输出相同(在Go游乐场上尝试):


2138589785

1871773944

另请注意,Go 将字符串存储为内存中的 UTF-8 字节序列,并为字符串(如 )编制索引,即 UTF-8 序列。这在您的示例中很好,因为所有输入字符都使用单个字节进行编码,但如果输入包含多字节字符,您将获得不同的结果。char[x]


要正确处理所有情况,请使用一个简单的字符串:返回连续的符文,该符文也是 的别名,因此您可以获得所需的代码点。for rangeint32


此外,检查空字符串是不必要的,如果它是空的,则不会执行循环主体。另外:这是一个没有操作,只需删除它。sum &= sum


简化版本:


func CountChars(s string) (sum int32) {

    for _, r := range s {

        sum = (sum << 5) - sum + r

    }

    return

}

测试它:


fmt.Println(CountChars("Google 世界"))

将输出与Javascript中相同的输出(在Go游乐场上尝试这个):


-815903459


查看完整回答
反对 回复 2022-09-26
?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

这是一个大小问题。JS 整数是 32 位,而 Go 整数不一定是 32 位。如果依赖于特定的 int 大小,则应通过将 的实例替换为 来指定它。intint32


那是什么样子的(游乐场):


package main


import (

    "fmt"

)


func main() {

    fmt.Println(CountChars("Google"))

    fmt.Println(CountChars("Google1"))

}


func CharCodeAt(s string, n int) int32 {

    return int32(s[n])

}


func CountChars(char string) int32 {

    var sum int32 = 0

    if char == "" {

        return sum

    }

    for x:=0; x<len(char); x++ {

        sum = (sum << 5) - sum + CharCodeAt(char, x)

        sum &= sum

    }

    return sum

}


查看完整回答
反对 回复 2022-09-26
  • 2 回答
  • 0 关注
  • 103 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号