英文:
Convert byte array of ASCII numeric characters to int using GO language
问题
我看到有一些关于我要问的完全相同问题的答案:如何在GO编程语言中将字节数组转换为整数?
我编写了下面的函数来将字节数组转换为整数:
func convertByteToInt(in []byte) int32 {
return (int32(in[0]) << 24 | int32(in[1]) << 16 | int32(in[2]) << 8 | int32(in[3]))
}
在此之前,我确保字节数组具有正确的(基于256)值。
in[0] = 54(6的ASCII码),
in[1] = 54(6的ASCII码),
in[2] = 49(1的ASCII码),
in[3] = 49(1的ASCII码)。
所以我期望从字节数组中获取整数6611的值,但实际上我得到了909521201。我无法理解在这样一个简单的转换中到底发生了什么。有人可以给我一些指导吗?
谢谢
英文:
I see some answers to exactly the same question I have: How to convert Byte array to int in GO programming language?
I wrote below function to convert byte array to int
func convertByteToInt(in []byte) int32 {
return (int32(in[0]) << 24 | int32(in[1]) << 16 | int32(in[2]) << 8 | int32(in[3]))
}
Before that, I made sure that byte array has correct(base 256) values.
in[0] = 54 (ASCII for 6),
in1 = 54 (ASCII for 6),
in[2] = 49 (ASCII for 1),
in[3] = 49 (ASCII for 1).
So I am expecting to retrieve integer 6611 value from byte array, but I ended up getting 909521201. I fail to understand what is exactly going on in such a simple conversion.
Can anyone flash some light?
THanks
答案1
得分: 15
@Volker在他的评论中是正确的,你的数组中没有一个二进制数,而是一个ASCII字符串。然而,你尝试将其解码为二进制。请注意,如果你处理的是二进制数,就没有必要验证任何输入(也许除了长度),因为所有单字节值都是有效的。
@Ainar-G给出了一种将ASCII数字转换为整数的方法。
比较这两种方法:(http://play.golang.org/p/_wufZ4P_aE)
buf := []byte{54, 54, 49, 49}
x, _ := strconv.Atoi(string(buf))
fmt.Println(x)
这将打印出6611;但看看这个:
var y int32
_ = binary.Read(bytes.NewReader(buf), binary.BigEndian, &y)
fmt.Println(y)
这将打印出909521201,所以正好是你得到的结果(并且不是你期望的)。顺便说一句,你手动解码的方式是BigEndian,所以最后这并不是一个“如此简单的转换”,因为还有一些其他因素需要考虑。
你手工转换ASCII的代码大致如下:
var x int32
for _, c := range in {
x = x*10 + int32(c - '0')
}
return x
但使用strconv
是更好的方法。
英文:
@Volker is right in his comment, you don't have a binary number in your array, you have an ASCII string. Yet, you try to decode it as binary. Note there's no need to validate any input (maybe except the length) if you were dealing with binary number, as all single byte values are valid.
@Ainar-G gave you a way of converting ASCII number into integer.
Compare these two approaches: (http://play.golang.org/p/_wufZ4P_aE)
buf := []byte{54, 54, 49, 49}
x, _ := strconv.Atoi(string(buf))
fmt.Println(x)
This prints 6611; but look at this:
var y int32
_ = binary.Read(bytes.NewReader(buf), binary.BigEndian, &y)
fmt.Println(y)
This prints 909521201, so exactly what you got (and didn't expect). As a side note, you're manually decoding it as BigEndian, so this is not "such a simple conversion" at the end, because there're some more factors to consider.
Your handcrafted conversion from ASCII would look more or less as follows:
var x int32
for _, c := range in {
x = x*10 + int32(c - '0')
}
return x
But using strconv
is the way to go.
答案2
得分: 2
将字节转换为字符串并使用strconv.Atoi
。
b := []byte{54, 54, 49, 49}
s := string(b)
i, err := strconv.Atoi(s)
if err != nil {
panic(err)
}
fmt.Println(i)
Playground: http://play.golang.org/p/NiobWHZ9gd
英文:
Convert your bytes to string and use strconv.Atoi
.
b := []byte{54, 54, 49, 49}
s := string(b)
i, err := strconv.Atoi(s)
if err != nil {
panic(err)
}
fmt.Println(i)
Playground: http://play.golang.org/p/NiobWHZ9gd
答案3
得分: 1
根据@tomasz的回答,如果你想以二进制格式存储一个数字,并且不关心字节序,你可以使用指针:
b := []byte{239, 190, 173, 222}
v := *(*uint32)(unsafe.Pointer(&b[0]))
fmt.Printf("0x%X\n", v)
fmt.Printf("%v", *(*[4]byte)(unsafe.Pointer(&v)))
英文:
Adding to @tomasz's answer, if you want to store a number in a binary format and don't care about endianess you can use pointers:
b := []byte{239, 190, 173, 222}
v := *(*uint32)(unsafe.Pointer(&b[0]))
fmt.Printf("0x%X\n", v)
fmt.Printf("%v", *(*[4]byte)(unsafe.Pointer(&v)))
<kbd>playground</kbd>
答案4
得分: 1
如果你只需要将一个简单的正整数值从[]byte
转换,比如这个例子[]byte{'6', '6', '1', '1'}
或[]byte{54, 54, 49, 49}
(它们是相同的),可以使用一个非常简单的for
循环来遍历[]byte
,将其转换为int
。代码如下:
var (
myInt, i int
myBytes = []byte{'6', '6', '1', '1'}
v byte
)
for ; i < len(myBytes); i++ {
v = myBytes[i] - '0'
myInt *= 10
myInt += int(v)
}
...就是这样。
你可以在Playground上查看完整的可运行代码。
英文:
If all you need is to convert a simple positive int
value that comes in a []byte
, like in this example []byte{'6', '6', '1', '1'}
or []byte{54, 54, 49, 49}
(which is the same), a very simple for
loop on the []byte
adding to an int
, will do the trick, just like this:
var (
myInt, i int
myBytes = []byte{'6', '6', '1', '1'}
v byte
)
for ; i < len(myBytes); i++ {
v = myBytes[i] - '0'
myInt *= 10
myInt += int(v)
}
...and that's all.
See the full working code in the Playground
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论