将ASCII数字字符的字节数组转换为整数,使用GO语言实现。

huangapple go评论86阅读模式
英文:

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] = 546的ASCII码),
in[1] = 546的ASCII码),
in[2] = 491的ASCII码),
in[3] = 491的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]) &lt;&lt; 24 | int32(in[1]) &lt;&lt; 16 | int32(in[2]) &lt;&lt; 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, &amp;y)
fmt.Println(y)

这将打印出909521201,所以正好是你得到的结果(并且不是你期望的)。顺便说一句,你手动解码的方式是BigEndian,所以最后这并不是一个“如此简单的转换”,因为还有一些其他因素需要考虑。

你手工转换ASCII的代码大致如下:

var x int32
for _, c := range in {
	x = x*10 + int32(c - &#39;0&#39;)
}
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, &amp;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 - &#39;0&#39;)
}
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)))

playground

英文:

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(&amp;b[0]))
fmt.Printf(&quot;0x%X\n&quot;, v)
fmt.Printf(&quot;%v&quot;, *(*[4]byte)(unsafe.Pointer(&amp;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{&#39;6&#39;, &#39;6&#39;, &#39;1&#39;, &#39;1&#39;} 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{&#39;6&#39;, &#39;6&#39;, &#39;1&#39;, &#39;1&#39;}
	v byte
)
for ; i &lt; len(myBytes); i++ {
    		v = myBytes[i] - &#39;0&#39;
    		myInt *= 10
    		myInt += int(v)
}

...and that's all.

See the full working code in the Playground

huangapple
  • 本文由 发表于 2014年12月4日 14:42:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/27287829.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定