Go int 유형의 최대 값


132

unsigned정수 유형으로 표현할 수있는 최대 값을 어떻게 지정 합니까?

min일부 구조체에서 최소 및 최대 길이를 반복적으로 계산하는 아래 루프에서 초기화하는 방법을 알고 싶습니다 .

var minLen uint = ???
var maxLen uint = 0
for _, thing := range sliceOfThings {
  if minLen > thing.n { minLen = thing.n }
  if maxLen < thing.n { maxLen = thing.n }
}
if minLen > maxLen {
  // If there are no values, clamp min at 0 so that min <= max.
  minLen = 0
}

비교를 통해 처음으로 minLen >= n.


2
golang.org/doc/effective_go.html#printingint(^uint(0) >> 1) // largest int
Victor

답변:


218

https://groups.google.com/group/golang-nuts/msg/71c307e4d73024ce?pli=1

독일 부분 :

정수 유형은 2의 보수 산술을 사용하므로 int및에 대한 최소 / 최대 상수 값을 유추 할 수 있습니다 uint. 예를 들어

const MaxUint = ^uint(0) 
const MinUint = 0 
const MaxInt = int(MaxUint >> 1) 
const MinInt = -MaxInt - 1

@CarelZA의 의견에 따라 :

uint8  : 0 to 255 
uint16 : 0 to 65535 
uint32 : 0 to 4294967295 
uint64 : 0 to 18446744073709551615 
int8   : -128 to 127 
int16  : -32768 to 32767 
int32  : -2147483648 to 2147483647 
int64  : -9223372036854775808 to 9223372036854775807

66
에서 사용할 수있는 것들을 사용 math: golang.org/pkg/math/#pkg-constants는 , 당신이 원하는 것이 math.MaxInt32대부분.
Charles L.

7
^ uint (0) 및 ^ uint (0) >> 1의 기능을 정확히 설명 할 수 있습니까?
Arijoon

16
@Arijoon, ^는 표현식에서 비트를 뒤집는 것을 의미하므로 uint (0) == 0000 ... 0000 (빌드 대상 아키텍처에 따라 정확히 32 또는 64 개의 0 비트) 다음 ^ unit (0) == 1111 ... 1111 이것은 우리에게 부호없는 정수 (모든 것)의 최대 값을 제공합니다. 이제 부호있는 정수에 대해 이야기 할 때 첫 번째 (가장 중요한) 비트가 부호를 int 최대 값으로 저장하는 데 사용됩니다. 우리는 모든 비트를 오른쪽으로 이동하여 ^ uint (0) >> 1 = = 0111 ... 1111. 최대 양의 정수를 제공합니다.
ninjaboy

4
@CharlesL. int 유형은 어떻습니까?
user960567

1
나는 시간이 지났다는 것을 알고 있지만 누군가 오늘 여기 와서 @ user960567의 Question-Comment를 볼 수 있습니다. int유형은 32 비트 시스템에서 32 비트 길이이고 64 비트 시스템에서 64 비트 길이입니다. 여기를 참조 하십시오 .
Christoph Harms-Ensink

73

물리적 유형 제한에 대한 https://golang.org/ref/spec#Numeric_types

최대 값은 math 패키지에 정의되므로 math.MaxUint32

오버플로가 없으므로 조심하십시오. 최대 값을 초과하면 증가합니다.


2
감사. 실제로을 사용 uint하고 uint32있습니다. lencap사용 int하지 int32그래서 나는 모든 아키텍처에 대한 사람들의 크기와 일치 사용 무언가를 원한다. 하나 또는 'int'에 대해서는 math/const.go무리를 정의합니다 . Max<type>uint
마이크 사무엘

uint32 또는 unit64로 변경 한 다음 아키텍처 전체에서 이식성이 있는지 확인했습니다. 나는 모든 것을 종교적으로 그렇게합니다. 아키텍처간에 C를 포팅하는 데 수년이 걸렸으며 "명시 적"이 나중에 도움이 될 것이라고 말할 수 있습니다.
삭제함

감사. 내 코드는 확인 uint(len(...)) < thing.minLen하지만 uint64(int)정의 된 동작 인지 여부를 모르겠습니다 .
마이크 사무엘

1
모르는 경우 위에 링크 된 사양 (특히 golang.org/doc/go_spec.html#Conversions)을 읽으십시오 . "숫자 유형 간 변환"에 대한 신중한 정의가 있습니다.
Anschel Schaffer-Cohen

29

math최대 값과 최소값을 얻기 위해 패키지를 사용 합니다.

func printMinMaxValue() {
    // integer max
    fmt.Printf("max int64 = %+v\n", math.MaxInt64)
    fmt.Printf("max int32 = %+v\n", math.MaxInt32)
    fmt.Printf("max int16 = %+v\n", math.MaxInt16)

    // integer min
    fmt.Printf("min int64 = %+v\n", math.MinInt64)
    fmt.Printf("min int32 = %+v\n", math.MinInt32)

    fmt.Printf("max flloat64= %+v\n", math.MaxFloat64)
    fmt.Printf("max float32= %+v\n", math.MaxFloat32)

    // etc you can see more int the `math`package
}

출력 :

max int64 = 9223372036854775807
max int32 = 2147483647
max int16 = 32767
min int64 = -9223372036854775808
min int32 = -2147483648
max flloat64= 1.7976931348623157e+308
max float32= 3.4028234663852886e+38

1
이 코드는 작동하지 않습니다. 두 개의 int64overflow int는 문자열 보간 전에 상수를 명시 적으로 입력하지 않으면 발생합니다. int64(math.MaxInt64)대신 사용 하십시오. stackoverflow.com/questions/16474594/…
domoarigato

3
그러나 그렇지 않으면 받아 들인 것보다 더 나은 대답입니다. :)
domoarigato

32 비트 워드 크기의 컴퓨터에서 int64를 사용하면 어떻게됩니까? C에서, 컴파일러는 INT_MIN 결정
segue_segway

12

나는 원래 @nmichaels가 그의 답변에 사용한 토론 스레드에서 가져온 코드를 사용했습니다. 이제 약간 다른 계산을 사용합니다. 다른 사람이 @Arijoon과 동일한 쿼리를 갖는 경우에 대한 의견을 포함했습니다.

const (
    MinUint uint = 0                 // binary: all zeroes

    // Perform a bitwise NOT to change every bit from 0 to 1
    MaxUint      = ^MinUint          // binary: all ones

    // Shift the binary number to the right (i.e. divide by two)
    // to change the high bit to 0
    MaxInt       = int(MaxUint >> 1) // binary: all ones except high bit

    // Perform another bitwise NOT to change the high bit to 1 and
    // all other bits to 0
    MinInt       = ^MaxInt           // binary: all zeroes except high bit
)

마지막 두 단계는 양수와 음수가 2의 보수 산술로 표현되는 방식으로 작동합니다. 숫자 유형 의 Go 언어 사양 섹션 은 관련 Wikipedia 기사를 참조하십시오 . 나는 그것을 읽지 못했지만 컴퓨터와 코딩의 기초에 매우 접근하기 쉬운 Charles Petzold 책에서 2의 보완에 대해 배웠습니다 .

위의 코드 (대부분의 주석 제외)를 작은 정수 수학 패키지에 넣었습니다 .


9

빠른 요약 :

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

배경:

나는 당신이 알고있는 가정으로, uint타입이 같은 크기는 하나 uint32또는 uint64, 당신이있어 플랫폼에 따라. 일반적으로 크기 지정이없는 버전은 플랫폼에 따라 "기본"유형을 사용할 수 있으므로 더 빠른 경향이 있으므로 최대 값에 근접 할 위험이없는 경우에만 크기가 조정되지 않은 버전을 사용합니다.

비원시 유형을 사용하려면 더 크거나 작은 정수를 에뮬레이트하기 위해 프로세서에서 추가 수학 및 경계 검사를 수행해야하기 때문에 "빠른"경향이 있습니다. 이를 염두에두고 프로세서 (또는 컴파일러의 최적화 된 코드)의 성능은 자신의 범위 검사 코드를 추가하는 것보다 거의 항상 더 좋을 것이므로 작동 할 위험이있는 경우 고정 크기 버전을 사용하고 최적화 된 에뮬레이션이 그로부터 발생하는 모든 오류를 처리하도록하는 것이 좋습니다.

그 말을하면서도, 당신이 작업하고있는 것을 아는 것이 유용한 상황이 여전히 있습니다.

" math / bits " 패키지 는의 크기를 비트 단위로 포함합니다 uint. 최대 값을 결정하려면 11에서 1을 뺀 비트 만큼 이동 하십시오.(1 << bits.UintSize) - 1

최대 값을 계산할 때는 uint일반적으로 값을 명시 적으로 uint(또는 더 큰) 변수 에 넣어야합니다 . 그렇지 않으면 해당 계산을 부호있는 int(어디에서와 같이) 할당하려고하면 컴파일러가 실패 할 수 있습니다. 적합하지 않을 것입니다.)

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

그것은 귀하의 질문에 대한 직접적인 대답이지만 관심이있을만한 몇 가지 관련 계산이 있습니다.

받는 사람에 따라 사양 , uint그리고 int항상 같은 크기입니다.

uint 32 또는 64 비트

int 와 같은 크기 uint

따라서이 상수를 사용하여 int동일한 답을 취하고 2뺄셈 하여 최대 값을 결정할 수도 있습니다 1. 즉 :(1 << bits.UintSize) / 2 - 1

그리고 그 최소 비트는 그 많은 비트 int만큼 이동 1하고 결과를로 나눕니다 -2. 즉 :(1 << bits.UintSize) / -2

요약해서 말하자면:

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

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

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

전체 예 (아래와 동일해야 함)

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)
}

감사. 기본 숫자에 대한주의 사항이 잘 설명되어 있으며 수학 / 비트를 몰랐습니다.
Mike Samuel

uint와 같은 크기 (int 또는 32 비트)입니다. 하나는 표시가 있고 다른 하나는 표시가 없으면 어떻게 같은 크기가 될 수 있습니까?
themiDdlest

비트 크기가 같고 최대 값 / 최소값이 동일하지 않습니다. 해당 크기의 비트 중 하나 부호 비트. ( /2부분은 int64의 최소 / 최대 크기를 계산할 때 고려에서 비트를 제거하는
것입니다


4

이 문제를 해결하는 한 가지 방법은 값 자체에서 시작점을 얻는 것입니다.

var minLen, maxLen uint
if len(sliceOfThings) > 0 {
  minLen = sliceOfThings[0].minLen
  maxLen = sliceOfThings[0].maxLen
  for _, thing := range sliceOfThings[1:] {
    if minLen > thing.minLen { minLen = thing.minLen }
    if maxLen < thing.maxLen { maxLen = thing.maxLen }
  }
}

1

경량 패키지 에는 다른 int 유형 제한 및 널리 사용되는 정수 함수뿐만 아니라 다음이 포함됩니다.

import (
    "fmt"
    "<Full URL>/go-imath/ix"
    "<Full URL>/go-imath/ux"
)
...
fmt.Println(ix.Minimal) // Output: -2147483648 (32-bit) or -9223372036854775808 (64-bit)
fmt.Println(ix.Maximal) // Output: 2147483647 or 9223372036854775807
fmt.Println(ux.Minimal) // Output: 0
fmt.Println(ux.Maximal) // Output: 4294967295 or 18446744073709551615

0
MaxInt8   = 1<<7 - 1
MinInt8   = -1 << 7
MaxInt16  = 1<<15 - 1
MinInt16  = -1 << 15
MaxInt32  = 1<<31 - 1
MinInt32  = -1 << 31
MaxInt64  = 1<<63 - 1
MinInt64  = -1 << 63
MaxUint8  = 1<<8 - 1
MaxUint16 = 1<<16 - 1
MaxUint32 = 1<<32 - 1
MaxUint64 = 1<<64 - 1
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.