Data type conversion: int to string, storing int to file as string or binary
I would like to record the things I'm learning, in English. To record knowledge and practise my English. Keep collecting streams, hoping one day to become rivers and seas.
For whom are computer science majors or experenced, these thing isn't a big deal. Actually it is the very basic thing.
For example:
var num uint32 = 12345
var str string = "12345"
In memory, these two variables should be like:
num: 00000000 00000000 00110000 00111001 4 bytes
str: 000000001 000000010 00000011 00000100 00000101 5 bytes
How convert the "num" to "str"? Maybe let try below idea.
func Uitostr(num uint32) []byte {
// uint ranges 0 ~ 4294967295
a := make([]byte, 10) //uint 最多10位数
i := len(a)
for num>0 {
// will get the remainder,and it is the last number in "num" as well
m := num%10
// ASCII code 48 represents "0"
a[i-1] = byte(m+48)
i--
//decimalism, 商向下取整(the quotient will be floored)
num /= 10
}
return a[i:]
}
In the package strconv of Golang, the functionformatBitswill do the work to convert int64 to string. The idea is samilar with this. In this function, a smart trick is implemented. This will accelerate the conversion when the decimal number is under 100.
onst nSmalls = 100
const smallsString = "00010203040506070809" +
"10111213141516171819" +
"20212223242526272829" +
"30313233343536373839" +
"40414243444546474849" +
"50515253545556575859" +
"60616263646566676869" +
"70717273747576777879" +
"80818283848586878889" +
"90919293949596979899"
us := uint(u)
for us >= 100 {
is := us % 100 * 2
us /= 100
i -= 2
a[i+1] = smallsString[is+1]
a[i+0] = smallsString[is+0]
}
// us < 100
is := us * 2
i--
a[i] = smallsString[is+1]
if us >= 10 {
i--
a[i] = smallsString[is]
}
In is := us % 100 * 2, us % 100 will get the last 2 numbers in us and implement it to the smallsSting. Amazing!
Anyway, when we get the []byte slience a, we can write them to a file.
myfd, _ := os.OpenFile("file.txt", os.O_CREATE | os.O_RDWR, 066)
defer myfd.Close()
myfd.Write(a)
In above, we convert the int to string([]byte actually) and store it to a file, how do we store int to a file as binary? To store int in a file as binary means store it as what it looks like in memory. So we should cut off the memory into several segments and store them in a []byte. It is how Golng did in the binary package.
func (littleEndian) PutUint32(b []byte, v uint32) {
_ = b[3] // early bounds check to guarantee safety of writes below
b[0] = byte(v)
b[1] = byte(v >> 8)
b[2] = byte(v >> 16)
b[3] = byte(v >> 24)
}
I have heard for many times that to store files in binary will save the disk space. Is it really true? I think it is not always. For example, we have a variable var nn int32 = 21, in memory it occupies 4 bytes, store it in binary it will occupy 4 bytes as well and 2 bytes if in string. If nn is bigger than a four-digit, indeed it will save disk space.
Below shows how it get the original uint32 from the []byte which stored the number as binary.
func (littleEndian) Uint32(b []byte) uint32 {
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
}
Next let's speculate which scenarios are more suitable to store data in binary or in string.
- It is meaningless to discuss to store characters in string or binary, because they are same. Only numbers(such int, float) have the difference between binary and string.
- When the numbers will be used to display, it is better to store in string. Maybe we can call "storing in string" as a display format. Becasue:
[]byte from file --> dispalyif storing in string[]byte from file as binary --> uint32 --> []byte as ASCII code --> displayif store in binary
- When just to store and the numbers will be used to calculate, it is better to store them in binary, becuase it will be more efficient to convert binarys to numbers than to convert []byte ASCII code to numbers. What's more, it will save disk space to store in binary when the number is bigger than a four-digit number. (Maybe in practise there is a trick to store small number as binary to save space, I don't know.)