The maximum value for an int type in Go

前端 未结 10 933
无人共我
无人共我 2021-01-29 19:09

How does one specify the maximum value representable for an unsigned integer type?

I would like to know how to initialize min in the loop below

10条回答
  •  说谎
    说谎 (楼主)
    2021-01-29 19:47

    Quick summary:

    import "math/bits"
    const (
        MaxUint uint = (1 << bits.UintSize) - 1
        MaxInt int = (1 << bits.UintSize) / 2 - 1
        MinInt int = (1 << bits.UintSize) / -2
    )
    

    Background:

    As I presume you know, the uint type is the same size as either uint32 or uint64, depending on the platform you're on. Usually, one would use the unsized version of these only when there is no risk of coming close to the maximum value, as the version without a size specification can use the "native" type, depending on platform, which tends to be faster.

    Note that it tends to be "faster" because using a non-native type sometimes requires additional math and bounds-checking to be performed by the processor, in order to emulate the larger or smaller integer. With that in mind, be aware that the performance of the processor (or compiler's optimised code) is almost always going to be better than adding your own bounds-checking code, so if there is any risk of it coming into play, it may make sense to simply use the fixed-size version, and let the optimised emulation handle any fallout from that.

    With that having been said, there are still some situations where it is useful to know what you're working with.

    The package "math/bits" contains the size of uint, in bits. To determine the maximum value, shift 1 by that many bits, minus 1. ie: (1 << bits.UintSize) - 1

    Note that when calculating the maximum value of uint, you'll generally need to put it explicitly into a uint (or larger) variable, otherwise the compiler may fail, as it will default to attempting to assign that calculation into a signed int (where, as should be obvious, it would not fit), so:

    const MaxUint uint = (1 << bits.UintSize) - 1
    

    That's the direct answer to your question, but there are also a couple of related calculations you may be interested in.

    According to the spec, uint and int are always the same size.

    uint either 32 or 64 bits

    int same size as uint

    So we can also use this constant to determine the maximum value of int, by taking that same answer and dividing by 2 then subtracting 1. ie: (1 << bits.UintSize) / 2 - 1

    And the minimum value of int, by shifting 1 by that many bits and dividing the result by -2. ie: (1 << bits.UintSize) / -2

    In summary:

    MaxUint: (1 << bits.UintSize) - 1

    MaxInt: (1 << bits.UintSize) / 2 - 1

    MinInt: (1 << bits.UintSize) / -2

    full example (should be the same as below)

    package main
    
    import "fmt"
    import "math"
    import "math/bits"
    
    func main() {
        var mi32 int64 = math.MinInt32
        var mi64 int64 = math.MinInt64
    
        var i32 uint64 = math.MaxInt32
        var ui32 uint64 = math.MaxUint32
        var i64 uint64 = math.MaxInt64
        var ui64 uint64 = math.MaxUint64
        var ui uint64 = (1 << bits.UintSize) - 1
        var i uint64 = (1 << bits.UintSize) / 2 - 1
        var mi int64 = (1 << bits.UintSize) / -2
    
        fmt.Printf(" MinInt32: %d\n", mi32)
        fmt.Printf(" MaxInt32:  %d\n", i32)
        fmt.Printf("MaxUint32:  %d\n", ui32)
        fmt.Printf(" MinInt64: %d\n", mi64)
        fmt.Printf(" MaxInt64:  %d\n", i64)
        fmt.Printf("MaxUint64:  %d\n", ui64)
        fmt.Printf("  MaxUint:  %d\n", ui)
        fmt.Printf("   MinInt: %d\n", mi)
        fmt.Printf("   MaxInt:  %d\n", i)
    }
    

提交回复
热议问题