Go returns 使用按位运算符的其他求和 javascript
Go returns other sum using bitwise operator than javascript
我尝试使用 Go 在 JS 中创建函数端口,但我遇到了一个奇怪的问题。函数的目标是对字符串中每个字母的 ascii 码求和。
一切正常,直到字符串长度 <= 6 之后去 returns 其他结果。
原文来自JS
function 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
}sd
c("Google") // returns 2138589785
c("Google1") // returns 1871773944
Go 中的端口
package main
import (
"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
}
Javascript 中的整数是 32 位的,而 Go 的 int
是架构相关的,可能是 32 位和 64 位。在 Go Playground 上它是 64 位的。由于每次迭代都左移 5,使用超过 6 个字符肯定会在 Javascript 中“溢出”(但在 Go 中还没有):7*5=35 > 32 bits
.
使用显式 32 位整数 (int32
) 以获得与 Javascript:
相同的输出
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 Playground 上尝试):
2138589785
1871773944
另请注意,Go 在内存中将字符串存储为 UTF-8 字节序列,并且索引字符串(如 char[x]
)会索引其字节,即 UTF-8 序列。这在您的示例中很好,因为所有输入字符都使用单个字节编码,但如果输入包含多字节字符,您将得到不同的结果。
要正确处理所有情况,请在字符串上使用简单的 for range
:即 returns 连续符文,这也是 int32
的别名,因此您可以得到代码你需要的积分。
另外不需要检查是否为空字符串,如果为空,则不会执行循环体。另外 sum &= sum
:这是一个空操作,只需删除它。
简化版:
func CountChars(s string) (sum int32) {
for _, r := range s {
sum = (sum << 5) - sum + r
}
return
}
正在测试:
fmt.Println(CountChars("Google 世界"))
将输出与 Javascript 相同的输出(在 Go Playground 上尝试这个):
-815903459
这是一个尺码问题。 JS int 是 32 位的,Go int 不一定是 32 位。如果您依赖于特定的 int 大小,则应通过将 int
的实例替换为 int32
.
来指定它
那看起来像什么 (playground):
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
}
我尝试使用 Go 在 JS 中创建函数端口,但我遇到了一个奇怪的问题。函数的目标是对字符串中每个字母的 ascii 码求和。
一切正常,直到字符串长度 <= 6 之后去 returns 其他结果。
原文来自JS
function 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
}sd
c("Google") // returns 2138589785
c("Google1") // returns 1871773944
Go 中的端口
package main
import (
"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
}
Javascript 中的整数是 32 位的,而 Go 的 int
是架构相关的,可能是 32 位和 64 位。在 Go Playground 上它是 64 位的。由于每次迭代都左移 5,使用超过 6 个字符肯定会在 Javascript 中“溢出”(但在 Go 中还没有):7*5=35 > 32 bits
.
使用显式 32 位整数 (int32
) 以获得与 Javascript:
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 Playground 上尝试):
2138589785
1871773944
另请注意,Go 在内存中将字符串存储为 UTF-8 字节序列,并且索引字符串(如 char[x]
)会索引其字节,即 UTF-8 序列。这在您的示例中很好,因为所有输入字符都使用单个字节编码,但如果输入包含多字节字符,您将得到不同的结果。
要正确处理所有情况,请在字符串上使用简单的 for range
:即 returns 连续符文,这也是 int32
的别名,因此您可以得到代码你需要的积分。
另外不需要检查是否为空字符串,如果为空,则不会执行循环体。另外 sum &= sum
:这是一个空操作,只需删除它。
简化版:
func CountChars(s string) (sum int32) {
for _, r := range s {
sum = (sum << 5) - sum + r
}
return
}
正在测试:
fmt.Println(CountChars("Google 世界"))
将输出与 Javascript 相同的输出(在 Go Playground 上尝试这个):
-815903459
这是一个尺码问题。 JS int 是 32 位的,Go int 不一定是 32 位。如果您依赖于特定的 int 大小,则应通过将 int
的实例替换为 int32
.
那看起来像什么 (playground):
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
}