diff --git a/all_test.go b/all_test.go index bbc3f0b..0302ce4 100644 --- a/all_test.go +++ b/all_test.go @@ -27,11 +27,20 @@ func r32() *FC32 { } var ( - r64lo = big.NewInt(math.MinInt64) - r64hi = big.NewInt(math.MaxInt64) - _3 = big.NewInt(3) + r64lo = big.NewInt(math.MinInt64) + r64hi = big.NewInt(math.MaxInt64) + _3 = big.NewInt(3) + MinIntM1 = MinInt + MaxIntP1 = MaxInt + MaxUintP1 uint = MaxUint ) +func init() { + MinIntM1-- + MaxIntP1++ + MaxUintP1++ +} + func r64() *FCBig { r, err := NewFCBig(r64lo, r64hi, true) if err != nil { @@ -2904,41 +2913,41 @@ func TestEnvelope(t *testing.T) { } func TestMaxInt(t *testing.T) { - n := int64(MaxInt()) + n := int64(MaxInt) if n != math.MaxInt32 && n != math.MaxInt64 { t.Error() } - t.Logf("64 bit ints: %t, MaxInt(): %d", n == math.MaxInt64, n) + t.Logf("64 bit ints: %t, MaxInt: %d", n == math.MaxInt64, n) } func TestMinInt(t *testing.T) { - n := int64(MinInt()) + n := int64(MinInt) if n != math.MinInt32 && n != math.MinInt64 { t.Error() } - t.Logf("64 bit ints: %t. MinInt(): %d", n == math.MinInt64, n) + t.Logf("64 bit ints: %t. MinInt: %d", n == math.MinInt64, n) } func TestMaxUint(t *testing.T) { - n := uint64(MaxUint()) + n := uint64(MaxUint) if n != math.MaxUint32 && n != math.MaxUint64 { t.Error() } - t.Logf("64 bit uints: %t. MaxUint(): %d", n == math.MaxUint64, n) + t.Logf("64 bit uints: %t. MaxUint: %d", n == math.MaxUint64, n) } func TestMax(t *testing.T) { tests := []struct{ a, b, e int }{ - {MinInt(), MinInt() - 1, MaxInt()}, - {MinInt() - 1, MinInt(), MaxInt()}, - {MinInt() - 1, MinInt() - 1, MaxInt()}, + {MinInt, MinIntM1, MaxInt}, + {MinIntM1, MinInt, MaxInt}, + {MinIntM1, MinIntM1, MaxInt}, - {MinInt(), MinInt(), MinInt()}, - {MinInt() + 1, MinInt(), MinInt() + 1}, - {MinInt(), MinInt() + 1, MinInt() + 1}, + {MinInt, MinInt, MinInt}, + {MinInt + 1, MinInt, MinInt + 1}, + {MinInt, MinInt + 1, MinInt + 1}, {-1, -1, -1}, {-1, 0, 0}, @@ -2952,13 +2961,13 @@ func TestMax(t *testing.T) { {1, 0, 1}, {1, 1, 1}, - {MaxInt(), MaxInt(), MaxInt()}, - {MaxInt() - 1, MaxInt(), MaxInt()}, - {MaxInt(), MaxInt() - 1, MaxInt()}, + {MaxInt, MaxInt, MaxInt}, + {MaxInt - 1, MaxInt, MaxInt}, + {MaxInt, MaxInt - 1, MaxInt}, - {MaxInt() + 1, MaxInt(), MaxInt()}, - {MaxInt(), MaxInt() + 1, MaxInt()}, - {MaxInt() + 1, MaxInt() + 1, MinInt()}, + {MaxIntP1, MaxInt, MaxInt}, + {MaxInt, MaxIntP1, MaxInt}, + {MaxIntP1, MaxIntP1, MinInt}, } for _, test := range tests { @@ -2970,13 +2979,13 @@ func TestMax(t *testing.T) { func TestMin(t *testing.T) { tests := []struct{ a, b, e int }{ - {MinInt() - 1, MinInt(), MinInt()}, - {MinInt(), MinInt() - 1, MinInt()}, - {MinInt() - 1, MinInt() - 1, MaxInt()}, + {MinIntM1, MinInt, MinInt}, + {MinInt, MinIntM1, MinInt}, + {MinIntM1, MinIntM1, MaxInt}, - {MinInt(), MinInt(), MinInt()}, - {MinInt() + 1, MinInt(), MinInt()}, - {MinInt(), MinInt() + 1, MinInt()}, + {MinInt, MinInt, MinInt}, + {MinInt + 1, MinInt, MinInt}, + {MinInt, MinInt + 1, MinInt}, {-1, -1, -1}, {-1, 0, -1}, @@ -2990,13 +2999,13 @@ func TestMin(t *testing.T) { {1, 0, 0}, {1, 1, 1}, - {MaxInt(), MaxInt(), MaxInt()}, - {MaxInt() - 1, MaxInt(), MaxInt() - 1}, - {MaxInt(), MaxInt() - 1, MaxInt() - 1}, + {MaxInt, MaxInt, MaxInt}, + {MaxInt - 1, MaxInt, MaxInt - 1}, + {MaxInt, MaxInt - 1, MaxInt - 1}, - {MaxInt() + 1, MaxInt(), MinInt()}, - {MaxInt(), MaxInt() + 1, MinInt()}, - {MaxInt() + 1, MaxInt() + 1, MinInt()}, + {MaxIntP1, MaxInt, MinInt}, + {MaxInt, MaxIntP1, MinInt}, + {MaxIntP1, MaxIntP1, MinInt}, } for _, test := range tests { @@ -3017,14 +3026,14 @@ func TestUMax(t *testing.T) { {11, 10, 11}, {11, 11, 11}, - {MaxUint(), MaxUint(), MaxUint()}, - {MaxUint(), MaxUint() - 1, MaxUint()}, - {MaxUint() - 1, MaxUint(), MaxUint()}, - {MaxUint() - 1, MaxUint() - 1, MaxUint() - 1}, + {MaxUint, MaxUint, MaxUint}, + {MaxUint, MaxUint - 1, MaxUint}, + {MaxUint - 1, MaxUint, MaxUint}, + {MaxUint - 1, MaxUint - 1, MaxUint - 1}, - {MaxUint(), MaxUint() + 1, MaxUint()}, - {MaxUint() + 1, MaxUint(), MaxUint()}, - {MaxUint() + 1, MaxUint() + 1, 0}, + {MaxUint, MaxUintP1, MaxUint}, + {MaxUintP1, MaxUint, MaxUint}, + {MaxUintP1, MaxUintP1, 0}, } for _, test := range tests { @@ -3045,14 +3054,14 @@ func TestUMin(t *testing.T) { {11, 10, 10}, {11, 11, 11}, - {MaxUint(), MaxUint(), MaxUint()}, - {MaxUint(), MaxUint() - 1, MaxUint() - 1}, - {MaxUint() - 1, MaxUint(), MaxUint() - 1}, - {MaxUint() - 1, MaxUint() - 1, MaxUint() - 1}, + {MaxUint, MaxUint, MaxUint}, + {MaxUint, MaxUint - 1, MaxUint - 1}, + {MaxUint - 1, MaxUint, MaxUint - 1}, + {MaxUint - 1, MaxUint - 1, MaxUint - 1}, - {MaxUint(), MaxUint() + 1, 0}, - {MaxUint() + 1, MaxUint(), 0}, - {MaxUint() + 1, MaxUint() + 1, 0}, + {MaxUint, MaxUintP1, 0}, + {MaxUintP1, MaxUint, 0}, + {MaxUintP1, MaxUintP1, 0}, } for _, test := range tests { diff --git a/bits.go b/bits.go index e9e29bc..a204b47 100644 --- a/bits.go +++ b/bits.go @@ -39,7 +39,7 @@ func BitLenUint32(n uint32) int { // BitLen returns the bit width of the non zero part of n. func BitLen(n int) int { // Should handle correctly [future] 64 bit Go ints - if n<<32 != 0 { + if IntBits == 64 { return BitLenUint64(uint64(n)) } @@ -60,7 +60,7 @@ func BitLen(n int) int { // Should handle correctly [future] 64 bit Go ints // BitLenUint returns the bit width of the non zero part of n. func BitLenUint(n uint) int { // Should handle correctly [future] 64 bit Go uints - if n<<32 != 0 { + if IntBits == 64 { return BitLenUint64(uint64(n)) } @@ -163,29 +163,29 @@ func PopCountUint32(n uint32) int { // PopCount returns population count of n (number of bits set in n). func PopCount(n int) int { // Should handle correctly [future] 64 bit Go ints - if n<<32 == 0 { - return PopCountUint32(uint32(n)) + if IntBits == 64 { + return PopCountUint64(uint64(n)) } - return PopCountUint64(uint64(n)) + return PopCountUint32(uint32(n)) } // PopCountUint returns population count of n (number of bits set in n). func PopCountUint(n uint) int { // Should handle correctly [future] 64 bit Go uints - if n<<32 == 0 { - return PopCountUint32(uint32(n)) + if IntBits == 64 { + return PopCountUint64(uint64(n)) } - return PopCountUint64(uint64(n)) + return PopCountUint32(uint32(n)) } // PopCountUintptr returns population count of n (number of bits set in n). func PopCountUintptr(n uintptr) int { - if n<<32 == 0 { - return PopCountUint32(uint32(n)) + if UintPtrBits == 64 { + return PopCountUint64(uint64(n)) } - return PopCountUint64(uint64(n)) + return PopCountUint32(uint32(n)) } // PopCountUint64 returns population count of n (number of bits set in n). diff --git a/mathutil.go b/mathutil.go index 9890f6f..36ad644 100644 --- a/mathutil.go +++ b/mathutil.go @@ -9,12 +9,38 @@ // // Compatibility issues // +// 2013-01-21: The following functions have been REMOVED +// +// func MaxInt() int +// func MinInt() int +// func MaxUint() uint +// func UintPtrBits() int +// +// They are now replaced by untyped constants +// +// MaxInt +// MinInt +// MaxUint +// UintPtrBits +// +// Additionally one more untyped constant was added +// +// IntBits +// +// This change breaks any existing code depending on the above removed +// functions. They should have not been published in the first place, that was +// unfortunate. Instead, defining such architecture and/or implementation +// specific integer limits and bit widths as untyped constants improves +// performance and allows for static dead code elimination if it depends on +// these values. Thanks to minux for pointing it out in the mail list +// (https://groups.google.com/d/msg/golang-nuts/tlPpLW6aJw8/NT3mpToH-a4J). +// // 2012-12-12: The following functions will be DEPRECATED with Go release // 1.0.3+1 and REMOVED with Go release 1.0.3+2, b/c of // http://code.google.com/p/go/source/detail?r=954a79ee3ea8 // -// func Uint64ToBigInt(n uint64) *big.Int -// func Uint64FromBigInt(n *big.Int) (uint64, bool) +// func Uint64ToBigInt(n uint64) *big.Int +// func Uint64FromBigInt(n *big.Int) (uint64, bool) package mathutil import ( @@ -22,6 +48,15 @@ import ( "math/big" ) +// Architecture and/or implementation specific integer limits and bit widths. +const ( + MaxInt = 1<<(IntBits-1) - 1 + MinInt = -MaxInt - 1 + MaxUint = 1<>32&1 + ^uint(0)>>16&1 + ^uint(0)>>8&1 + 3) + UintPtrBits = 1 << (^uintptr(0)>>32&1 + ^uintptr(0)>>16&1 + ^uintptr(0)>>8&1 + 3) +) + var ( _1 = big.NewInt(1) _2 = big.NewInt(2) @@ -603,50 +638,6 @@ func ProbablyPrimeBigInt(n, a *big.Int) bool { return false } -var ( - maxInt64 = int64(math.MaxInt64) - minInt64 = int64(math.MinInt64) - maxInt = int(math.MaxInt32) - minInt = int(math.MinInt32) - - maxUint64 = uint64(math.MaxUint64) - maxUint = uint(math.MaxUint32) -) - -func init() { - i, u := 1, uint(1) - if i, u = i<<32, u<<32; (i != 0) != (u != 0) { - panic("Specs violation") // http://golang.org/ref/spec#Numeric_types - } - - // Silly things required to support both int=32b and int=64b Go editions. - if n := 1; n<<32 != 0 { - maxInt, minInt = int(maxInt64), int(minInt64) - maxUint = uint(maxUint64) - } -} - -// MaxInt returns the largest int value. On systems where int is 32 bit this is -// the same value as math.MaxInt32. On systems where int is 64 bit this is the -// same value as math.MaxInt64. -func MaxInt() int { - return maxInt -} - -// MinInt returns the smallest int value. On systems where int is 32 bit this -// is the same value as math.MinInt32. On systems where int is 64 bit this is -// the same value as math.MinInt64. -func MinInt() int { - return minInt -} - -// MaxUint returns the largest uint value. On systems where uint is 32 bit this -// is the same value as math.MaxUint32. On systems where int is 64 bit this is -// the same value as math.MaxUint64. -func MaxUint() uint { - return maxUint -} - // Max returns the larger of a and b. func Max(a, b int) int { if a > b {