The textbook you are looking for is
The Go Programming Language Specification
Numeric types
A numeric type represents sets of integer or floating-point values. The predeclared architecture-independent numeric types are:
uint32 set of all unsigned 32-bit integers (0 to 4294967295) uint64 set of all unsigned 64-bit integers (0 to 18446744073709551615) int32 set of all signed 32-bit integers (-2147483648 to 2147483647) int64 set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)There is also a set of predeclared numeric types with implementation-specific sizes:
uint either 32 or 64 bits int same size as uint
Check the size of type int. On the Go Playground it's 4 bytes or 32 bits.
package main
import (
"fmt"
"runtime"
"unsafe"
)
func main() {
fmt.Println("arch", runtime.GOARCH)
fmt.Println("int", unsafe.Sizeof(int(0)))
}
Playground: https://play.golang.org/p/2A6ODvhb1Dx
Output (Playground):
arch amd64p32
int 4
Run the program in your (LeetCode) environment. It's likely 8 bytes or 64 bits.
For example, in my environment,
Output (Local):
arch amd64
int 8
Here are some fixes to your code,
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Println(runtime.GOARCH)
fmt.Printf("%v\n", singleNumber([]int{-2, -2, 1, 1, -3, 1, -3, -3, -4, -2}))
}
func singleNumber(nums []int) int {
sum := make([]int, 64)
for _, v := range nums {
for i := range sum {
sum[i] += 1 & (v >> uint(i))
}
}
res := 0
for k, v := range sum {
if (v % 3) != 0 {
res |= (v % 3) << uint(k)
}
}
fmt.Printf("res %+v\n", res)
return res
}
Playground: https://play.golang.org/p/kaoSuesu2Oj
Output (Playground):
amd64p32
res -4
-4
Output (Local):
amd64
res -4
-4
Answer from peterSO on Stack OverflowThis is possibly a stupid question, but I come from JS and i just started learning GO. Now as you may know in JS everything is Number but in GO there are int, int8, 32, 64. So, I was wandering should i get in habit of using specific int type or just use int in 99% of cases? What’s the advantage and when do you guys use it in real life if you do?
I have a field in my data which is small enough to simply use an int32. However, from what I can tell, int32 is generally used when representing a code point or something quite specific, rather than using it simply to save 32 bits of storage. Also, some of the stdlib packages (like strconv) deal exclusively with int64 rather than int32. This has meant changes to my code I didn't expect purely to handle int32 things.
What is your opinion (and perhaps the general consensus) on using int32 purely for efficiency purposes? Is it just worth using an int64 for simplicity?
tbh, this raises confusing if you were programming in java or cpp
https://golang.org/pkg/builtin/#int
int is a signed integer type that is at least 32 bits in size. It is a distinct type, however, and not an alias for, say, int32.
Surprised no one mentioned that int usually has 64 bits on 64-bit systems and 32 bits on 32-bit systems. The distinction from both int32 and int64 is clear.
One line answer is fmt.Sprint(i).
Anyway there are many conversions, even inside standard library function like fmt.Sprint(i), so you have some options (try The Go Playground):
1- You may write your conversion function (Fastest):
func String(n int32) string {
buf := [11]byte{}
pos := len(buf)
i := int64(n)
signed := i < 0
if signed {
i = -i
}
for {
pos--
buf[pos], i = '0'+byte(i%10), i/10
if i == 0 {
if signed {
pos--
buf[pos] = '-'
}
return string(buf[pos:])
}
}
}
2- You may use fmt.Sprint(i) (Slow)
See inside:
// Sprint formats using the default formats for its operands and returns the resulting string.
// Spaces are added between operands when neither is a string.
func Sprint(a ...interface{}) string {
p := newPrinter()
p.doPrint(a)
s := string(p.buf)
p.free()
return s
}
3- You may use strconv.Itoa(int(i)) (Fast)
See inside:
// Itoa is shorthand for FormatInt(int64(i), 10).
func Itoa(i int) string {
return FormatInt(int64(i), 10)
}
4- You may use strconv.FormatInt(int64(i), 10) (Faster)
See inside:
// FormatInt returns the string representation of i in the given base,
// for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'
// for digit values >= 10.
func FormatInt(i int64, base int) string {
_, s := formatBits(nil, uint64(i), base, i < 0, false)
return s
}
Comparison & Benchmark (with 50000000 iterations):
s = String(i) takes: 5.5923198s
s = String2(i) takes: 5.5923199s
s = strconv.FormatInt(int64(i), 10) takes: 5.9133382s
s = strconv.Itoa(int(i)) takes: 5.9763418s
s = fmt.Sprint(i) takes: 13.5697761s
Code:
package main
import (
"fmt"
//"strconv"
"time"
)
func main() {
var s string
i := int32(-2147483648)
t := time.Now()
for j := 0; j < 50000000; j++ {
s = String(i) //5.5923198s
//s = String2(i) //5.5923199s
//s = strconv.FormatInt(int64(i), 10) // 5.9133382s
//s = strconv.Itoa(int(i)) //5.9763418s
//s = fmt.Sprint(i) // 13.5697761s
}
fmt.Println(time.Since(t))
fmt.Println(s)
}
func String(n int32) string {
buf := [11]byte{}
pos := len(buf)
i := int64(n)
signed := i < 0
if signed {
i = -i
}
for {
pos--
buf[pos], i = '0'+byte(i%10), i/10
if i == 0 {
if signed {
pos--
buf[pos] = '-'
}
return string(buf[pos:])
}
}
}
func String2(n int32) string {
buf := [11]byte{}
pos := len(buf)
i, q := int64(n), int64(0)
signed := i < 0
if signed {
i = -i
}
for {
pos--
q = i / 10
buf[pos], i = '0'+byte(i-10*q), q
if i == 0 {
if signed {
pos--
buf[pos] = '-'
}
return string(buf[pos:])
}
}
}
The Sprint function converts a given value to string.
package main
import (
"fmt"
)
func main() {
var sampleInt int32 = 1
sampleString := fmt.Sprint(sampleInt)
fmt.Printf("%+V %+V\n", sampleInt, sampleString)
}
// %!V(int32=+1) %!V(string=1)
See this example.
func ParseInt(s string, base int, bitSize int) (i int64, err error)
ParseInt always returns int64.
bitSize defines the range of values.
If the value corresponding to s cannot be represented by a signed integer of the given size, err.Err = ErrRange.
http://golang.org/pkg/strconv/#ParseInt
type int int
int is a signed integer type that is at least 32 bits in size. It is a distinct type, however, and not an alias for, say, int32.
http://golang.org/pkg/builtin/#int
So int could be bigger than 32 bit in the future or on some systems like int in C.
I guess on some systems int64 might be faster than int32 because that system only works with 64-bit integers.
Here is an example of an error when bitSize is 8:
http://play.golang.org/p/_osjMqL6Nj
package main
import (
"fmt"
"strconv"
)
func main() {
i, err := strconv.ParseInt("123456", 10, 8)
fmt.Println(i, err)
}
Package strconv
func ParseInt
func ParseInt(s string, base int, bitSize int) (i int64, err error)ParseInt interprets a string s in the given base (2 to 36) and returns the corresponding value i. If base == 0, the base is implied by the string's prefix: base 16 for "0x", base 8 for "0", and base 10 otherwise.
The bitSize argument specifies the integer type that the result must fit into. Bit sizes 0, 8, 16, 32, and 64 correspond to int, int8, int16, int32, and int64.
The errors that ParseInt returns have concrete type *NumError and include err.Num = s. If s is empty or contains invalid digits, err.Err = ErrSyntax; if the value corresponding to s cannot be represented by a signed integer of the given size, err.Err = ErrRange.
ParseInt always returns an int64 value. Depending on bitSize, this value will fit into int, int8, int16, int32, or int64. If the value cannot be represented by a signed integer of the size given by bitSize, then err.Err = ErrRange.
The Go Programming Language Specification
Numeric types
The value of an n-bit integer is n bits wide and represented using two's complement arithmetic.
int8 the set of all signed 8-bit integers (-128 to 127) int16 the set of all signed 16-bit integers (-32768 to 32767) int32 the set of all signed 32-bit integers (-2147483648 to 2147483647) int64 the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)There is also a set of predeclared numeric types with implementation-specific sizes:
uint either 32 or 64 bits int same size as uint
int is either 32 or 64 bits, depending on the implementation. Usually it's 32 bits for 32-bit compilers and 64 bits for 64-bit compilers.
To find out the size of an int or uint, use strconv.IntSize.
Package strconv
Constants
const IntSize = intSize
IntSizeis the size in bits of anintoruintvalue.
For example,
package main
import (
"fmt"
"runtime"
"strconv"
)
func main() {
fmt.Println(runtime.Compiler, runtime.GOARCH, runtime.GOOS)
fmt.Println(strconv.IntSize)
}
Output:
gc amd64 linux
64
I have the following function, it works flawlessly
func (r *system) Quantity() int32 {
// r.info.Quantity is type int
return int32(r.info.Quantity)
}Now I'm trying to cast it to *int32
func (r *system) Quantity() *int32 {
// r.info.Quantity is type int
return int32(&r.info.Quantity)
}
But i get the following error cannot use &r.info.Quantity (type *int) as type *int32 in return argument, and of course it seems logic...is there a way to achieve this?
From what I understand, the size of the int type in Go is platform dependent.
From the docs (tour):
The int, uint, and uintptr types are usually 32 bits wide on 32-bit systems and 64 bits wide on 64-bit systems. When you need an integer value you should use int unless you have a specific reason to use a sized or unsigned integer type.
So, on a 32-bit system, if I did something like this:
var myUint32 uint32 = 4294967295 // max positive value for uint32 myInt := int(myUint32)
what would happen to myInt on a 32-bit system? I can't seem to find docs for this. Would the bitwise value remain the same in memory (and using a bit as a sign bit)? Or would there be truncation of some sort? I am unsure. I also don't have a quick way to test this out.
backstory, I have code in review that was suggested to be written like this:
func myFunc (a, b uint32) int {
return int(a) - int(b)
}I have a really bad feeling about this, especially since our code planned to be open source. There is no guarantee what architecture this will run on. But I need solid evidence argue we shouldn't do this.
Usually each platform operates best with integral type of its native size.
By using simple int you say to your compiler that you don't really care about what bit width to use and you let him choose the one it will work fastest with. Note, that you always want to write your code so that it is as platform independent as possible...
On the other hand int32 / int64 types are useful if you need the integer to be of a specific size. This might be useful f.e. if you want to save binary files (don't forget about endiannes). Or if you have large array of integers (that will only reach up to 32b value), where saving half the memory would be significant, etc.
Usually size of int is equal to the natural word size of target. So if your program doesn't care for the size of int (Minimal int range is enough), it can perform best on variety of compilers.
When you need a specific size, you can of course use int32 etc.
Simply Use the int() cast function
The Go Programming Language Specification
Conversions
Conversions are expressions of the form
T(x)whereTis a type andxis an expression that can be converted to typeT.
For example,
size := binary.BigEndian.Uint32(b[4:])
n, err := rdr.Discard(int(size))