如何指定
我想知道如何在下面的循环中初始化
1 2 3 4 5 6 7 8 9 10 | 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 } |
以便第一次通过比较
-
看看从golang.org/doc/effective_go.html#printing中提取的此片段
int(^uint(0) >> 1) largest int
https://groups.google.com/group/golang-nuts/msg/71c307e4d73024ce?pli=1
德语部分:
Since integer types use two's complement arithmetic, you can infer the
min/max constant values forint anduint . For example,
1
2
3
4 const MaxUint = ^uint(0)
const MinUint = 0
const MaxInt = int(MaxUint >> 1)
const MinInt = -MaxInt - 1
根据@CarelZA的评论:
1 2 3 4 5 6 7 8 | 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 |
-
使用
math 中可用的内容:golang.org/pkg/math/#pkg-constants,您最希望math.MaxInt32 。 - 有人可以确切解释^ uint(0)和^ uint(0)>> 1做什么吗?
- @Arijoon,^表示表达式中的反转位,因此如果:uint(0)== 0000 ... 0000(取决于构建目标体系结构,则为32或64个零位),则^ unit(0)== 1111 ... 1111这为我们提供了无符号整数(全1)的最大值。现在,当您谈论带符号的整数时,第一个(最高有效)位用于存储符号,因此为带符号的int最大值-我们需要将所有位右移,这使我们获得^ uint(0)>> 1 = = 0111 ... 1111。给出最大正整数。
- @CharlesL。只是int类型呢?
-
我知道已经有一段时间了,但是以防万一有人今天来到这里并看到@ user960567s问题注释:
int 类型在32位系统上为32位长,在64位系统上为64位长。看这里。 -
这种脆性和不透明性,并与二进制补码表示联系在一起吗?为什么不使用
math.MaxInt16 等? - @Jehan,因为有关int和int的主题是int32或int 64,不能为int16。
https://golang.org/ref/spec#Numeric_types了解物理类型限制。
最大值在math软件包中定义,因此在您的情况下为:math.MaxUint32
当心,因为没有溢出-超过最大值会导致环绕。
-
谢谢。我实际上使用的是
uint ,而不是uint32 。len 和cap 使用的是int 而不是int32 ,因此我想使用与所有体系结构的大小都匹配的东西。mathconst.go 定义了一堆Max ,但没有为uint 或`int定义。 - 将其ID更改为uint32或unit64,然后确保其可跨体系结构移植。我认真地做所有事情。在将C移植到体系结构之间已经经历了多年的艰辛,我可以说"显式"将在以后提供很大帮助。
-
谢谢。我的代码检查了
uint(len(...)) < thing.minLen ,但我不知道uint64(int) 是否并且将保持定义的行为。 - 如果您不知道,请阅读上面链接的规范...特别是golang.org/doc/go_spec.html#Conversions。对于"数字类型之间的转换"有一个仔细的定义。
我将使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | func printMinMaxValue() { // integer max fmt.Printf("max int64 = %+v\ ", math.MaxInt64) fmt.Printf("max int32 = %+v\ ", math.MaxInt32) fmt.Printf("max int16 = %+v\ ", math.MaxInt16) // integer min fmt.Printf("min int64 = %+v\ ", math.MinInt64) fmt.Printf("min int32 = %+v\ ", math.MinInt32) fmt.Printf("max flloat64= %+v\ ", math.MaxFloat64) fmt.Printf("max float32= %+v\ ", math.MaxFloat32) // etc you can see more int the `math`package } |
Ouput:
1 2 3 4 5 6 7 | 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 |
-
此代码不起作用。两个
int64 s溢出int,如果没有在字符串插值之前显式键入常量,则会发生这种情况。请使用int64(math.MaxInt64) ,请参阅stackoverflow.com/questions/16474594/ - 但除此之外,这是一个比公认的更好的答案。 :)
- 如果在32位字长的计算机上使用int64,会发生什么情况?在C中,编译器决定INT_MIN
我最初使用了@nmichaels在他的答案中使用的讨论线程中的代码。我现在使用略有不同的计算。如果其他人与@Arijoon有相同的查询,我已经添加了一些评论
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 ) |
后两个步骤之所以有效,是因为在二进制补码运算中正数和负数的表示方式。有关数字类型的Go语言规范部分,请读者参考相关的Wikipedia文章。我还没有读过,但是我确实从Charles Petzold的《代码》一书中了解了二进制补码,这是对计算机和编码基础知识的入门。
我将上面的代码(减去了大部分注释)放入了一个小的整数数学包中。
快速总结:
1 2 3 4 5 6 | import"math/bits" const ( MaxUint uint = (1 << bits.UintSize) - 1 MaxInt int = (1 << bits.UintSize) / 2 - 1 MinInt int = (1 << bits.UintSize) / -2 ) |
背景:
如我所知,
请注意,它趋向于"更快",因为使用非本机类型有时需要处理器执行额外的数学运算和边界检查,以模拟更大或更小的整数。考虑到这一点,请注意,处理器(或编译器的优化代码)的性能几乎总是比添加自己的边界检查代码更好,因此,如果有发挥作用的风险,它可能会使简单地使用固定大小的版本,并让优化的仿真处理由此产生的任何后果是合理的。
说了这么多,在某些情况下了解您正在使用的内容很有用。
包" math / bits"包含
请注意,在计算
1 | const MaxUint uint = (1 << bits.UintSize) - 1 |
这是您问题的直接答案,但是您可能会对一些相关的计算感兴趣。
根据规范,
uint either 32 or 64 bits
int same size asuint
因此,我们也可以使用该常数来确定
和
综上所述:
MaxUint:
MaxInt:
MinInt:
完整示例(应与以下相同)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 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\ ", mi32) fmt.Printf(" MaxInt32: %d\ ", i32) fmt.Printf("MaxUint32: %d\ ", ui32) fmt.Printf(" MinInt64: %d\ ", mi64) fmt.Printf(" MaxInt64: %d\ ", i64) fmt.Printf("MaxUint64: %d\ ", ui64) fmt.Printf(" MaxUint: %d\ ", ui) fmt.Printf(" MinInt: %d\ ", mi) fmt.Printf(" MaxInt: %d\ ", i) } |
- 谢谢。您对本机数字的注意事项已明确陈述,我不知道数学/位。
- uint 32或64位,int与uint相同。如果一个有一个符号而另一个没有一个符号,它们怎么能一样大小?
-
它们具有相同的位大小,没有相同的最大值/最小值。该大小的位之一是符号位。 (
2 部分是在计算int64的最小/最大大小时从考虑中除去该位的部分)
来自数学库:https://github.com/golang/go/blob/master/src/math/const.go#L39
1 2 3 4 5 6 7 8 9 10 11 | package main import ( "fmt" "math" ) func main() { fmt.Printf("max int64: %d\ ", math.MaxInt64) } |
解决此问题的一种方法是从值本身获取起点:
1 2 3 4 5 6 7 8 9 | 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 2 3 4 5 6 7 8 9 10 11 12 13 14 | const ( 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 ) |
一个轻量级的软件包包含它们(以及其他int类型限制和一些广泛使用的整数函数):
1 2 3 4 5 6 7 8 9 10 | 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 |
1 2 3 4 5 6 7 8 9 10 11 12 | 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 |