| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  |  | // Copyright (c) 2014 The mathutil Authors. All rights reserved. | 
					
						
							|  |  |  |  | // Use of this source code is governed by a BSD-style | 
					
						
							|  |  |  |  | // license that can be found in the LICENSE file. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Package mathutil provides utilities supplementing the standard 'math' and | 
					
						
							|  |  |  |  | // 'math/rand' packages. | 
					
						
							|  |  |  |  | // | 
					
						
							| 
									
										
										
										
											2025-02-14 16:54:10 +00:00
										 |  |  |  | // # Release history and compatibility issues | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  |  | // | 
					
						
							|  |  |  |  | // 2020-12-20 v1.2.1 fixes MulOverflowInt64. | 
					
						
							|  |  |  |  | // | 
					
						
							|  |  |  |  | // 2020-12-19 Added {Add,Sub,Mul}OverflowInt{8,16,32,64} | 
					
						
							|  |  |  |  | // | 
					
						
							|  |  |  |  | // 2018-10-21 Added BinaryLog | 
					
						
							|  |  |  |  | // | 
					
						
							|  |  |  |  | // 2018-04-25: New functions for determining Max/Min of nullable values. Ex: | 
					
						
							| 
									
										
										
										
											2025-02-14 16:54:10 +00:00
										 |  |  |  | // | 
					
						
							|  |  |  |  | //	func MaxPtr(a, b *int) *int { | 
					
						
							|  |  |  |  | //	func MinPtr(a, b *int) *int { | 
					
						
							|  |  |  |  | //	func MaxBytePtr(a, b *byte) *byte { | 
					
						
							|  |  |  |  | //	func MinBytePtr(a, b *byte) *byte { | 
					
						
							|  |  |  |  | //	... | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  |  | // | 
					
						
							|  |  |  |  | // 2017-10-14: New variadic functions for Max/Min. Ex: | 
					
						
							| 
									
										
										
										
											2025-02-14 16:54:10 +00:00
										 |  |  |  | // | 
					
						
							|  |  |  |  | //	func MaxVal(val int, vals ...int) int { | 
					
						
							|  |  |  |  | //	func MinVal(val int, vals ...int) int { | 
					
						
							|  |  |  |  | //	func MaxByteVal(val byte, vals ...byte) byte { | 
					
						
							|  |  |  |  | //	func MinByteVal(val byte, vals ...byte) byte { | 
					
						
							|  |  |  |  | //	... | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  |  | // | 
					
						
							|  |  |  |  | // 2016-10-10: New functions QuadPolyDiscriminant and QuadPolyFactors. | 
					
						
							|  |  |  |  | // | 
					
						
							|  |  |  |  | // 2013-12-13: The following functions have been REMOVED | 
					
						
							|  |  |  |  | // | 
					
						
							| 
									
										
										
										
											2025-02-14 16:54:10 +00:00
										 |  |  |  | //	func Uint64ToBigInt(n uint64) *big.Int | 
					
						
							|  |  |  |  | //	func Uint64FromBigInt(n *big.Int) (uint64, bool) | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  |  | // | 
					
						
							|  |  |  |  | // 2013-05-13: The following functions are now DEPRECATED | 
					
						
							|  |  |  |  | // | 
					
						
							| 
									
										
										
										
											2025-02-14 16:54:10 +00:00
										 |  |  |  | //	func Uint64ToBigInt(n uint64) *big.Int | 
					
						
							|  |  |  |  | //	func Uint64FromBigInt(n *big.Int) (uint64, bool) | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  |  | // | 
					
						
							|  |  |  |  | // These functions will be REMOVED with Go release 1.1+1. | 
					
						
							|  |  |  |  | // | 
					
						
							|  |  |  |  | // 2013-01-21: The following functions have been REMOVED | 
					
						
							|  |  |  |  | // | 
					
						
							| 
									
										
										
										
											2025-02-14 16:54:10 +00:00
										 |  |  |  | //	func MaxInt() int | 
					
						
							|  |  |  |  | //	func MinInt() int | 
					
						
							|  |  |  |  | //	func MaxUint() uint | 
					
						
							|  |  |  |  | //	func UintPtrBits() int | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  |  | // | 
					
						
							|  |  |  |  | // They are now replaced by untyped constants | 
					
						
							|  |  |  |  | // | 
					
						
							| 
									
										
										
										
											2025-02-14 16:54:10 +00:00
										 |  |  |  | //	MaxInt | 
					
						
							|  |  |  |  | //	MinInt | 
					
						
							|  |  |  |  | //	MaxUint | 
					
						
							|  |  |  |  | //	UintPtrBits | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  |  | // | 
					
						
							|  |  |  |  | // Additionally one more untyped constant was added | 
					
						
							|  |  |  |  | // | 
					
						
							| 
									
										
										
										
											2025-02-14 16:54:10 +00:00
										 |  |  |  | //	IntBits | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  |  | // | 
					
						
							|  |  |  |  | // 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 | 
					
						
							|  |  |  |  | // | 
					
						
							| 
									
										
										
										
											2025-02-14 16:54:10 +00:00
										 |  |  |  | //	func Uint64ToBigInt(n uint64) *big.Int | 
					
						
							|  |  |  |  | //	func Uint64FromBigInt(n *big.Int) (uint64, bool) | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  |  | package mathutil // import "modernc.org/mathutil" | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | import ( | 
					
						
							|  |  |  |  | 	"math" | 
					
						
							|  |  |  |  | 	"math/big" | 
					
						
							|  |  |  |  | ) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Architecture and/or implementation specific integer limits and bit widths. | 
					
						
							|  |  |  |  | const ( | 
					
						
							|  |  |  |  | 	MaxInt      = 1<<(IntBits-1) - 1 | 
					
						
							|  |  |  |  | 	MinInt      = -MaxInt - 1 | 
					
						
							|  |  |  |  | 	MaxUint     = 1<<IntBits - 1 | 
					
						
							|  |  |  |  | 	IntBits     = 1 << (^uint(0)>>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) | 
					
						
							|  |  |  |  | ) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // GCDByte returns the greatest common divisor of a and b. Based on: | 
					
						
							|  |  |  |  | // http://en.wikipedia.org/wiki/Euclidean_algorithm#Implementations | 
					
						
							|  |  |  |  | func GCDByte(a, b byte) byte { | 
					
						
							|  |  |  |  | 	for b != 0 { | 
					
						
							|  |  |  |  | 		a, b = b, a%b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return a | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // GCDUint16 returns the greatest common divisor of a and b. | 
					
						
							|  |  |  |  | func GCDUint16(a, b uint16) uint16 { | 
					
						
							|  |  |  |  | 	for b != 0 { | 
					
						
							|  |  |  |  | 		a, b = b, a%b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return a | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // GCDUint32 returns the greatest common divisor of a and b. | 
					
						
							|  |  |  |  | func GCDUint32(a, b uint32) uint32 { | 
					
						
							|  |  |  |  | 	for b != 0 { | 
					
						
							|  |  |  |  | 		a, b = b, a%b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return a | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // GCDUint64 returns the greatest common divisor of a and b. | 
					
						
							|  |  |  |  | func GCDUint64(a, b uint64) uint64 { | 
					
						
							|  |  |  |  | 	for b != 0 { | 
					
						
							|  |  |  |  | 		a, b = b, a%b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return a | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ISqrt returns floor(sqrt(n)). Typical run time is few hundreds of ns. | 
					
						
							|  |  |  |  | func ISqrt(n uint32) (x uint32) { | 
					
						
							|  |  |  |  | 	if n == 0 { | 
					
						
							|  |  |  |  | 		return | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if n >= math.MaxUint16*math.MaxUint16 { | 
					
						
							|  |  |  |  | 		return math.MaxUint16 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	var px, nx uint32 | 
					
						
							|  |  |  |  | 	for x = n; ; px, x = x, nx { | 
					
						
							|  |  |  |  | 		nx = (x + n/x) / 2 | 
					
						
							|  |  |  |  | 		if nx == x || nx == px { | 
					
						
							|  |  |  |  | 			break | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // SqrtUint64 returns floor(sqrt(n)). Typical run time is about 0.5 µs. | 
					
						
							|  |  |  |  | func SqrtUint64(n uint64) (x uint64) { | 
					
						
							|  |  |  |  | 	if n == 0 { | 
					
						
							|  |  |  |  | 		return | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if n >= math.MaxUint32*math.MaxUint32 { | 
					
						
							|  |  |  |  | 		return math.MaxUint32 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	var px, nx uint64 | 
					
						
							|  |  |  |  | 	for x = n; ; px, x = x, nx { | 
					
						
							|  |  |  |  | 		nx = (x + n/x) / 2 | 
					
						
							|  |  |  |  | 		if nx == x || nx == px { | 
					
						
							|  |  |  |  | 			break | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // SqrtBig returns floor(sqrt(n)). It panics on n < 0. | 
					
						
							|  |  |  |  | func SqrtBig(n *big.Int) (x *big.Int) { | 
					
						
							|  |  |  |  | 	switch n.Sign() { | 
					
						
							|  |  |  |  | 	case -1: | 
					
						
							|  |  |  |  | 		panic(-1) | 
					
						
							|  |  |  |  | 	case 0: | 
					
						
							|  |  |  |  | 		return big.NewInt(0) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	var px, nx big.Int | 
					
						
							|  |  |  |  | 	x = big.NewInt(0) | 
					
						
							|  |  |  |  | 	x.SetBit(x, n.BitLen()/2+1, 1) | 
					
						
							|  |  |  |  | 	for { | 
					
						
							|  |  |  |  | 		nx.Rsh(nx.Add(x, nx.Div(n, x)), 1) | 
					
						
							|  |  |  |  | 		if nx.Cmp(x) == 0 || nx.Cmp(&px) == 0 { | 
					
						
							|  |  |  |  | 			break | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 		px.Set(x) | 
					
						
							|  |  |  |  | 		x.Set(&nx) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Log2Byte returns log base 2 of n. It's the same as index of the highest | 
					
						
							|  |  |  |  | // bit set in n.  For n == 0 -1 is returned. | 
					
						
							|  |  |  |  | func Log2Byte(n byte) int { | 
					
						
							|  |  |  |  | 	return log2[n] | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Log2Uint16 returns log base 2 of n. It's the same as index of the highest | 
					
						
							|  |  |  |  | // bit set in n.  For n == 0 -1 is returned. | 
					
						
							|  |  |  |  | func Log2Uint16(n uint16) int { | 
					
						
							|  |  |  |  | 	if b := n >> 8; b != 0 { | 
					
						
							|  |  |  |  | 		return log2[b] + 8 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return log2[n] | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Log2Uint32 returns log base 2 of n. It's the same as index of the highest | 
					
						
							|  |  |  |  | // bit set in n.  For n == 0 -1 is returned. | 
					
						
							|  |  |  |  | func Log2Uint32(n uint32) int { | 
					
						
							|  |  |  |  | 	if b := n >> 24; b != 0 { | 
					
						
							|  |  |  |  | 		return log2[b] + 24 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if b := n >> 16; b != 0 { | 
					
						
							|  |  |  |  | 		return log2[b] + 16 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if b := n >> 8; b != 0 { | 
					
						
							|  |  |  |  | 		return log2[b] + 8 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return log2[n] | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Log2Uint64 returns log base 2 of n. It's the same as index of the highest | 
					
						
							|  |  |  |  | // bit set in n.  For n == 0 -1 is returned. | 
					
						
							|  |  |  |  | func Log2Uint64(n uint64) int { | 
					
						
							|  |  |  |  | 	if b := n >> 56; b != 0 { | 
					
						
							|  |  |  |  | 		return log2[b] + 56 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if b := n >> 48; b != 0 { | 
					
						
							|  |  |  |  | 		return log2[b] + 48 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if b := n >> 40; b != 0 { | 
					
						
							|  |  |  |  | 		return log2[b] + 40 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if b := n >> 32; b != 0 { | 
					
						
							|  |  |  |  | 		return log2[b] + 32 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if b := n >> 24; b != 0 { | 
					
						
							|  |  |  |  | 		return log2[b] + 24 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if b := n >> 16; b != 0 { | 
					
						
							|  |  |  |  | 		return log2[b] + 16 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if b := n >> 8; b != 0 { | 
					
						
							|  |  |  |  | 		return log2[b] + 8 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return log2[n] | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ModPowByte computes (b^e)%m. It panics for m == 0 || b == e == 0. | 
					
						
							|  |  |  |  | // | 
					
						
							|  |  |  |  | // See also: http://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method | 
					
						
							|  |  |  |  | func ModPowByte(b, e, m byte) byte { | 
					
						
							|  |  |  |  | 	if b == 0 && e == 0 { | 
					
						
							|  |  |  |  | 		panic(0) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if m == 1 { | 
					
						
							|  |  |  |  | 		return 0 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	r := uint16(1) | 
					
						
							|  |  |  |  | 	for b, m := uint16(b), uint16(m); e > 0; b, e = b*b%m, e>>1 { | 
					
						
							|  |  |  |  | 		if e&1 == 1 { | 
					
						
							|  |  |  |  | 			r = r * b % m | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return byte(r) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ModPowUint16 computes (b^e)%m. It panics for m == 0 || b == e == 0. | 
					
						
							|  |  |  |  | func ModPowUint16(b, e, m uint16) uint16 { | 
					
						
							|  |  |  |  | 	if b == 0 && e == 0 { | 
					
						
							|  |  |  |  | 		panic(0) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if m == 1 { | 
					
						
							|  |  |  |  | 		return 0 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	r := uint32(1) | 
					
						
							|  |  |  |  | 	for b, m := uint32(b), uint32(m); e > 0; b, e = b*b%m, e>>1 { | 
					
						
							|  |  |  |  | 		if e&1 == 1 { | 
					
						
							|  |  |  |  | 			r = r * b % m | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return uint16(r) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ModPowUint32 computes (b^e)%m. It panics for m == 0 || b == e == 0. | 
					
						
							|  |  |  |  | func ModPowUint32(b, e, m uint32) uint32 { | 
					
						
							|  |  |  |  | 	if b == 0 && e == 0 { | 
					
						
							|  |  |  |  | 		panic(0) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if m == 1 { | 
					
						
							|  |  |  |  | 		return 0 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	r := uint64(1) | 
					
						
							|  |  |  |  | 	for b, m := uint64(b), uint64(m); e > 0; b, e = b*b%m, e>>1 { | 
					
						
							|  |  |  |  | 		if e&1 == 1 { | 
					
						
							|  |  |  |  | 			r = r * b % m | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return uint32(r) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ModPowUint64 computes (b^e)%m. It panics for m == 0 || b == e == 0. | 
					
						
							|  |  |  |  | func ModPowUint64(b, e, m uint64) (r uint64) { | 
					
						
							|  |  |  |  | 	if b == 0 && e == 0 { | 
					
						
							|  |  |  |  | 		panic(0) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if m == 1 { | 
					
						
							|  |  |  |  | 		return 0 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return modPowBigInt(big.NewInt(0).SetUint64(b), big.NewInt(0).SetUint64(e), big.NewInt(0).SetUint64(m)).Uint64() | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | func modPowBigInt(b, e, m *big.Int) (r *big.Int) { | 
					
						
							|  |  |  |  | 	r = big.NewInt(1) | 
					
						
							|  |  |  |  | 	for i, n := 0, e.BitLen(); i < n; i++ { | 
					
						
							|  |  |  |  | 		if e.Bit(i) != 0 { | 
					
						
							|  |  |  |  | 			r.Mod(r.Mul(r, b), m) | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 		b.Mod(b.Mul(b, b), m) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ModPowBigInt computes (b^e)%m. Returns nil for e < 0. It panics for m == 0 || b == e == 0. | 
					
						
							|  |  |  |  | func ModPowBigInt(b, e, m *big.Int) (r *big.Int) { | 
					
						
							|  |  |  |  | 	if b.Sign() == 0 && e.Sign() == 0 { | 
					
						
							|  |  |  |  | 		panic(0) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if m.Cmp(_1) == 0 { | 
					
						
							|  |  |  |  | 		return big.NewInt(0) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if e.Sign() < 0 { | 
					
						
							|  |  |  |  | 		return | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return modPowBigInt(big.NewInt(0).Set(b), big.NewInt(0).Set(e), m) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | var uint64ToBigIntDelta big.Int | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | func init() { | 
					
						
							|  |  |  |  | 	uint64ToBigIntDelta.SetBit(&uint64ToBigIntDelta, 63, 1) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | var uintptrBits int | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | func init() { | 
					
						
							|  |  |  |  | 	x := uint64(math.MaxUint64) | 
					
						
							|  |  |  |  | 	uintptrBits = BitLenUintptr(uintptr(x)) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // UintptrBits returns the bit width of an uintptr at the executing machine. | 
					
						
							|  |  |  |  | func UintptrBits() int { | 
					
						
							|  |  |  |  | 	return uintptrBits | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // AddUint128_64 returns the uint128 sum of uint64 a and b. | 
					
						
							|  |  |  |  | func AddUint128_64(a, b uint64) (hi uint64, lo uint64) { | 
					
						
							|  |  |  |  | 	lo = a + b | 
					
						
							|  |  |  |  | 	if lo < a { | 
					
						
							|  |  |  |  | 		hi = 1 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return hi, lo | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MulUint128_64 returns the uint128 bit product of uint64 a and b. | 
					
						
							|  |  |  |  | func MulUint128_64(a, b uint64) (hi, lo uint64) { | 
					
						
							|  |  |  |  | 	/* | 
					
						
							|  |  |  |  | 		2^(2 W) ahi bhi + 2^W alo bhi + 2^W ahi blo + alo blo | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		FEDCBA98 76543210 FEDCBA98 76543210 | 
					
						
							|  |  |  |  | 		                  ---- alo*blo ---- | 
					
						
							|  |  |  |  | 		         ---- alo*bhi ---- | 
					
						
							|  |  |  |  | 		         ---- ahi*blo ---- | 
					
						
							|  |  |  |  | 		---- ahi*bhi ---- | 
					
						
							|  |  |  |  | 	*/ | 
					
						
							|  |  |  |  | 	const w = 32 | 
					
						
							|  |  |  |  | 	const m = 1<<w - 1 | 
					
						
							|  |  |  |  | 	ahi, bhi, alo, blo := a>>w, b>>w, a&m, b&m | 
					
						
							|  |  |  |  | 	lo = alo * blo | 
					
						
							|  |  |  |  | 	mid1 := alo * bhi | 
					
						
							|  |  |  |  | 	mid2 := ahi * blo | 
					
						
							|  |  |  |  | 	c1, lo := AddUint128_64(lo, mid1<<w) | 
					
						
							|  |  |  |  | 	c2, lo := AddUint128_64(lo, mid2<<w) | 
					
						
							|  |  |  |  | 	_, hi = AddUint128_64(ahi*bhi, mid1>>w+mid2>>w+c1+c2) | 
					
						
							|  |  |  |  | 	return | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // PowerizeBigInt returns (e, p) such that e is the smallest number for which p | 
					
						
							|  |  |  |  | // == b^e is greater or equal n. For n < 0 or b < 2 (0, nil) is returned. | 
					
						
							|  |  |  |  | // | 
					
						
							|  |  |  |  | // NOTE: Run time for large values of n (above about 2^1e6 ~= 1e300000) can be | 
					
						
							|  |  |  |  | // significant and/or unacceptabe.  For any smaller values of n the function | 
					
						
							|  |  |  |  | // typically performs in sub second time.  For "small" values of n (cca bellow | 
					
						
							|  |  |  |  | // 2^1e3 ~= 1e300) the same can be easily below 10 µs. | 
					
						
							|  |  |  |  | // | 
					
						
							|  |  |  |  | // A special (and trivial) case of b == 2 is handled separately and performs | 
					
						
							|  |  |  |  | // much faster. | 
					
						
							|  |  |  |  | func PowerizeBigInt(b, n *big.Int) (e uint32, p *big.Int) { | 
					
						
							|  |  |  |  | 	switch { | 
					
						
							|  |  |  |  | 	case b.Cmp(_2) < 0 || n.Sign() < 0: | 
					
						
							|  |  |  |  | 		return | 
					
						
							|  |  |  |  | 	case n.Sign() == 0 || n.Cmp(_1) == 0: | 
					
						
							|  |  |  |  | 		return 0, big.NewInt(1) | 
					
						
							|  |  |  |  | 	case b.Cmp(_2) == 0: | 
					
						
							|  |  |  |  | 		p = big.NewInt(0) | 
					
						
							|  |  |  |  | 		e = uint32(n.BitLen() - 1) | 
					
						
							|  |  |  |  | 		p.SetBit(p, int(e), 1) | 
					
						
							|  |  |  |  | 		if p.Cmp(n) < 0 { | 
					
						
							|  |  |  |  | 			p.Mul(p, _2) | 
					
						
							|  |  |  |  | 			e++ | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 		return | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	bw := b.BitLen() | 
					
						
							|  |  |  |  | 	nw := n.BitLen() | 
					
						
							|  |  |  |  | 	p = big.NewInt(1) | 
					
						
							|  |  |  |  | 	var bb, r big.Int | 
					
						
							|  |  |  |  | 	for { | 
					
						
							|  |  |  |  | 		switch p.Cmp(n) { | 
					
						
							|  |  |  |  | 		case -1: | 
					
						
							|  |  |  |  | 			x := uint32((nw - p.BitLen()) / bw) | 
					
						
							|  |  |  |  | 			if x == 0 { | 
					
						
							|  |  |  |  | 				x = 1 | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 			e += x | 
					
						
							|  |  |  |  | 			switch x { | 
					
						
							|  |  |  |  | 			case 1: | 
					
						
							|  |  |  |  | 				p.Mul(p, b) | 
					
						
							|  |  |  |  | 			default: | 
					
						
							|  |  |  |  | 				r.Set(_1) | 
					
						
							|  |  |  |  | 				bb.Set(b) | 
					
						
							|  |  |  |  | 				e := x | 
					
						
							|  |  |  |  | 				for { | 
					
						
							|  |  |  |  | 					if e&1 != 0 { | 
					
						
							|  |  |  |  | 						r.Mul(&r, &bb) | 
					
						
							|  |  |  |  | 					} | 
					
						
							|  |  |  |  | 					if e >>= 1; e == 0 { | 
					
						
							|  |  |  |  | 						break | 
					
						
							|  |  |  |  | 					} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 					bb.Mul(&bb, &bb) | 
					
						
							|  |  |  |  | 				} | 
					
						
							|  |  |  |  | 				p.Mul(p, &r) | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 		case 0, 1: | 
					
						
							|  |  |  |  | 			return | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // PowerizeUint32BigInt returns (e, p) such that e is the smallest number for | 
					
						
							|  |  |  |  | // which p == b^e is greater or equal n. For n < 0 or b < 2 (0, nil) is | 
					
						
							|  |  |  |  | // returned. | 
					
						
							|  |  |  |  | // | 
					
						
							|  |  |  |  | // More info: see PowerizeBigInt. | 
					
						
							|  |  |  |  | func PowerizeUint32BigInt(b uint32, n *big.Int) (e uint32, p *big.Int) { | 
					
						
							|  |  |  |  | 	switch { | 
					
						
							|  |  |  |  | 	case b < 2 || n.Sign() < 0: | 
					
						
							|  |  |  |  | 		return | 
					
						
							|  |  |  |  | 	case n.Sign() == 0 || n.Cmp(_1) == 0: | 
					
						
							|  |  |  |  | 		return 0, big.NewInt(1) | 
					
						
							|  |  |  |  | 	case b == 2: | 
					
						
							|  |  |  |  | 		p = big.NewInt(0) | 
					
						
							|  |  |  |  | 		e = uint32(n.BitLen() - 1) | 
					
						
							|  |  |  |  | 		p.SetBit(p, int(e), 1) | 
					
						
							|  |  |  |  | 		if p.Cmp(n) < 0 { | 
					
						
							|  |  |  |  | 			p.Mul(p, _2) | 
					
						
							|  |  |  |  | 			e++ | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 		return | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	var bb big.Int | 
					
						
							|  |  |  |  | 	bb.SetInt64(int64(b)) | 
					
						
							|  |  |  |  | 	return PowerizeBigInt(&bb, n) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* | 
					
						
							|  |  |  |  | ProbablyPrimeUint32 returns true if n is prime or n is a pseudoprime to base a. | 
					
						
							|  |  |  |  | It implements the Miller-Rabin primality test for one specific value of 'a' and | 
					
						
							|  |  |  |  | k == 1. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Wrt pseudocode shown at | 
					
						
							|  |  |  |  | http://en.wikipedia.org/wiki/Miller-Rabin_primality_test#Algorithm_and_running_time | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-14 16:54:10 +00:00
										 |  |  |  | 	Input: n > 3, an odd integer to be tested for primality; | 
					
						
							|  |  |  |  | 	Input: k, a parameter that determines the accuracy of the test | 
					
						
							|  |  |  |  | 	Output: composite if n is composite, otherwise probably prime | 
					
						
							|  |  |  |  | 	write n − 1 as 2^s·d with d odd by factoring powers of 2 from n − 1 | 
					
						
							|  |  |  |  | 	LOOP: repeat k times: | 
					
						
							|  |  |  |  | 	   pick a random integer a in the range [2, n − 2] | 
					
						
							|  |  |  |  | 	   x ← a^d mod n | 
					
						
							|  |  |  |  | 	   if x = 1 or x = n − 1 then do next LOOP | 
					
						
							|  |  |  |  | 	   for r = 1 .. s − 1 | 
					
						
							|  |  |  |  | 	      x ← x^2 mod n | 
					
						
							|  |  |  |  | 	      if x = 1 then return composite | 
					
						
							|  |  |  |  | 	      if x = n − 1 then do next LOOP | 
					
						
							|  |  |  |  | 	   return composite | 
					
						
							|  |  |  |  | 	return probably prime | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | ... this function behaves like passing 1 for 'k' and additionally a | 
					
						
							|  |  |  |  | fixed/non-random 'a'.  Otherwise it's the same algorithm. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | See also: http://mathworld.wolfram.com/Rabin-MillerStrongPseudoprimeTest.html | 
					
						
							|  |  |  |  | */ | 
					
						
							|  |  |  |  | func ProbablyPrimeUint32(n, a uint32) bool { | 
					
						
							|  |  |  |  | 	d, s := n-1, 0 | 
					
						
							|  |  |  |  | 	for ; d&1 == 0; d, s = d>>1, s+1 { | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	x := uint64(ModPowUint32(a, d, n)) | 
					
						
							|  |  |  |  | 	if x == 1 || uint32(x) == n-1 { | 
					
						
							|  |  |  |  | 		return true | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	for ; s > 1; s-- { | 
					
						
							|  |  |  |  | 		if x = x * x % uint64(n); x == 1 { | 
					
						
							|  |  |  |  | 			return false | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		if uint32(x) == n-1 { | 
					
						
							|  |  |  |  | 			return true | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return false | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ProbablyPrimeUint64_32 returns true if n is prime or n is a pseudoprime to | 
					
						
							|  |  |  |  | // base a. It implements the Miller-Rabin primality test for one specific value | 
					
						
							|  |  |  |  | // of 'a' and k == 1.  See also ProbablyPrimeUint32. | 
					
						
							|  |  |  |  | func ProbablyPrimeUint64_32(n uint64, a uint32) bool { | 
					
						
							|  |  |  |  | 	d, s := n-1, 0 | 
					
						
							|  |  |  |  | 	for ; d&1 == 0; d, s = d>>1, s+1 { | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	x := ModPowUint64(uint64(a), d, n) | 
					
						
							|  |  |  |  | 	if x == 1 || x == n-1 { | 
					
						
							|  |  |  |  | 		return true | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	bx, bn := big.NewInt(0).SetUint64(x), big.NewInt(0).SetUint64(n) | 
					
						
							|  |  |  |  | 	for ; s > 1; s-- { | 
					
						
							|  |  |  |  | 		if x = bx.Mod(bx.Mul(bx, bx), bn).Uint64(); x == 1 { | 
					
						
							|  |  |  |  | 			return false | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		if x == n-1 { | 
					
						
							|  |  |  |  | 			return true | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return false | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ProbablyPrimeBigInt_32 returns true if n is prime or n is a pseudoprime to | 
					
						
							|  |  |  |  | // base a. It implements the Miller-Rabin primality test for one specific value | 
					
						
							|  |  |  |  | // of 'a' and k == 1.  See also ProbablyPrimeUint32. | 
					
						
							|  |  |  |  | func ProbablyPrimeBigInt_32(n *big.Int, a uint32) bool { | 
					
						
							|  |  |  |  | 	var d big.Int | 
					
						
							|  |  |  |  | 	d.Set(n) | 
					
						
							|  |  |  |  | 	d.Sub(&d, _1) // d <- n-1 | 
					
						
							|  |  |  |  | 	s := 0 | 
					
						
							|  |  |  |  | 	for ; d.Bit(s) == 0; s++ { | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	nMinus1 := big.NewInt(0).Set(&d) | 
					
						
							|  |  |  |  | 	d.Rsh(&d, uint(s)) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	x := ModPowBigInt(big.NewInt(int64(a)), &d, n) | 
					
						
							|  |  |  |  | 	if x.Cmp(_1) == 0 || x.Cmp(nMinus1) == 0 { | 
					
						
							|  |  |  |  | 		return true | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	for ; s > 1; s-- { | 
					
						
							|  |  |  |  | 		if x = x.Mod(x.Mul(x, x), n); x.Cmp(_1) == 0 { | 
					
						
							|  |  |  |  | 			return false | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		if x.Cmp(nMinus1) == 0 { | 
					
						
							|  |  |  |  | 			return true | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return false | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ProbablyPrimeBigInt returns true if n is prime or n is a pseudoprime to base | 
					
						
							|  |  |  |  | // a. It implements the Miller-Rabin primality test for one specific value of | 
					
						
							|  |  |  |  | // 'a' and k == 1.  See also ProbablyPrimeUint32. | 
					
						
							|  |  |  |  | func ProbablyPrimeBigInt(n, a *big.Int) bool { | 
					
						
							|  |  |  |  | 	var d big.Int | 
					
						
							|  |  |  |  | 	d.Set(n) | 
					
						
							|  |  |  |  | 	d.Sub(&d, _1) // d <- n-1 | 
					
						
							|  |  |  |  | 	s := 0 | 
					
						
							|  |  |  |  | 	for ; d.Bit(s) == 0; s++ { | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	nMinus1 := big.NewInt(0).Set(&d) | 
					
						
							|  |  |  |  | 	d.Rsh(&d, uint(s)) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	x := ModPowBigInt(a, &d, n) | 
					
						
							|  |  |  |  | 	if x.Cmp(_1) == 0 || x.Cmp(nMinus1) == 0 { | 
					
						
							|  |  |  |  | 		return true | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	for ; s > 1; s-- { | 
					
						
							|  |  |  |  | 		if x = x.Mod(x.Mul(x, x), n); x.Cmp(_1) == 0 { | 
					
						
							|  |  |  |  | 			return false | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		if x.Cmp(nMinus1) == 0 { | 
					
						
							|  |  |  |  | 			return true | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return false | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Max returns the larger of a and b. | 
					
						
							|  |  |  |  | func Max(a, b int) int { | 
					
						
							|  |  |  |  | 	if a > b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Min returns the smaller of a and b. | 
					
						
							|  |  |  |  | func Min(a, b int) int { | 
					
						
							|  |  |  |  | 	if a < b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxPtr returns a pointer to the larger of a and b, or nil. | 
					
						
							|  |  |  |  | func MaxPtr(a, b *int) *int { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a > *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinPtr returns a pointer to the smaller of a and b, or nil. | 
					
						
							|  |  |  |  | func MinPtr(a, b *int) *int { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a < *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxVal returns the largest argument passed. | 
					
						
							|  |  |  |  | func MaxVal(val int, vals ...int) int { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v > res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinVal returns the smallest argument passed. | 
					
						
							|  |  |  |  | func MinVal(val int, vals ...int) int { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v < res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Clamp returns a value restricted between lo and hi. | 
					
						
							|  |  |  |  | func Clamp(v, lo, hi int) int { | 
					
						
							|  |  |  |  | 	return Min(Max(v, lo), hi) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // UMax returns the larger of a and b. | 
					
						
							|  |  |  |  | func UMax(a, b uint) uint { | 
					
						
							|  |  |  |  | 	if a > b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // UMin returns the smaller of a and b. | 
					
						
							|  |  |  |  | func UMin(a, b uint) uint { | 
					
						
							|  |  |  |  | 	if a < b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // UMaxPtr returns a pointer to the larger of a and b, or nil. | 
					
						
							|  |  |  |  | func UMaxPtr(a, b *uint) *uint { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a > *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // UMinPtr returns a pointer to the smaller of a and b, or nil. | 
					
						
							|  |  |  |  | func UMinPtr(a, b *uint) *uint { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a < *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // UMaxVal returns the largest argument passed. | 
					
						
							|  |  |  |  | func UMaxVal(val uint, vals ...uint) uint { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v > res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // UMinVal returns the smallest argument passed. | 
					
						
							|  |  |  |  | func UMinVal(val uint, vals ...uint) uint { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v < res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // UClamp returns a value restricted between lo and hi. | 
					
						
							|  |  |  |  | func UClamp(v, lo, hi uint) uint { | 
					
						
							|  |  |  |  | 	return UMin(UMax(v, lo), hi) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxByte returns the larger of a and b. | 
					
						
							|  |  |  |  | func MaxByte(a, b byte) byte { | 
					
						
							|  |  |  |  | 	if a > b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinByte returns the smaller of a and b. | 
					
						
							|  |  |  |  | func MinByte(a, b byte) byte { | 
					
						
							|  |  |  |  | 	if a < b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxBytePtr returns a pointer to the larger of a and b, or nil. | 
					
						
							|  |  |  |  | func MaxBytePtr(a, b *byte) *byte { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a > *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinBytePtr returns a pointer to the smaller of a and b, or nil. | 
					
						
							|  |  |  |  | func MinBytePtr(a, b *byte) *byte { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a < *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxByteVal returns the largest argument passed. | 
					
						
							|  |  |  |  | func MaxByteVal(val byte, vals ...byte) byte { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v > res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinByteVal returns the smallest argument passed. | 
					
						
							|  |  |  |  | func MinByteVal(val byte, vals ...byte) byte { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v < res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ClampByte returns a value restricted between lo and hi. | 
					
						
							|  |  |  |  | func ClampByte(v, lo, hi byte) byte { | 
					
						
							|  |  |  |  | 	return MinByte(MaxByte(v, lo), hi) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxInt8 returns the larger of a and b. | 
					
						
							|  |  |  |  | func MaxInt8(a, b int8) int8 { | 
					
						
							|  |  |  |  | 	if a > b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinInt8 returns the smaller of a and b. | 
					
						
							|  |  |  |  | func MinInt8(a, b int8) int8 { | 
					
						
							|  |  |  |  | 	if a < b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxInt8Ptr returns a pointer to the larger of a and b, or nil. | 
					
						
							|  |  |  |  | func MaxInt8Ptr(a, b *int8) *int8 { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a > *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinInt8Ptr returns a pointer to the smaller of a and b, or nil. | 
					
						
							|  |  |  |  | func MinInt8Ptr(a, b *int8) *int8 { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a < *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxInt8Val returns the largest argument passed. | 
					
						
							|  |  |  |  | func MaxInt8Val(val int8, vals ...int8) int8 { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v > res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinInt8Val returns the smallest argument passed. | 
					
						
							|  |  |  |  | func MinInt8Val(val int8, vals ...int8) int8 { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v < res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ClampInt8 returns a value restricted between lo and hi. | 
					
						
							|  |  |  |  | func ClampInt8(v, lo, hi int8) int8 { | 
					
						
							|  |  |  |  | 	return MinInt8(MaxInt8(v, lo), hi) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxUint16 returns the larger of a and b. | 
					
						
							|  |  |  |  | func MaxUint16(a, b uint16) uint16 { | 
					
						
							|  |  |  |  | 	if a > b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinUint16 returns the smaller of a and b. | 
					
						
							|  |  |  |  | func MinUint16(a, b uint16) uint16 { | 
					
						
							|  |  |  |  | 	if a < b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxUint16Ptr returns a pointer to the larger of a and b, or nil. | 
					
						
							|  |  |  |  | func MaxUint16Ptr(a, b *uint16) *uint16 { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a > *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinUint16Ptr returns a pointer to the smaller of a and b, or nil. | 
					
						
							|  |  |  |  | func MinUint16Ptr(a, b *uint16) *uint16 { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a < *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxUint16Val returns the largest argument passed. | 
					
						
							|  |  |  |  | func MaxUint16Val(val uint16, vals ...uint16) uint16 { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v > res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinUint16Val returns the smallest argument passed. | 
					
						
							|  |  |  |  | func MinUint16Val(val uint16, vals ...uint16) uint16 { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v < res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ClampUint16 returns a value restricted between lo and hi. | 
					
						
							|  |  |  |  | func ClampUint16(v, lo, hi uint16) uint16 { | 
					
						
							|  |  |  |  | 	return MinUint16(MaxUint16(v, lo), hi) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxInt16 returns the larger of a and b. | 
					
						
							|  |  |  |  | func MaxInt16(a, b int16) int16 { | 
					
						
							|  |  |  |  | 	if a > b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinInt16 returns the smaller of a and b. | 
					
						
							|  |  |  |  | func MinInt16(a, b int16) int16 { | 
					
						
							|  |  |  |  | 	if a < b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxInt16Ptr returns a pointer to the larger of a and b, or nil. | 
					
						
							|  |  |  |  | func MaxInt16Ptr(a, b *int16) *int16 { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a > *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinInt16Ptr returns a pointer to the smaller of a and b, or nil. | 
					
						
							|  |  |  |  | func MinInt16Ptr(a, b *int16) *int16 { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a < *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxInt16Val returns the largest argument passed. | 
					
						
							|  |  |  |  | func MaxInt16Val(val int16, vals ...int16) int16 { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v > res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinInt16Val returns the smallest argument passed. | 
					
						
							|  |  |  |  | func MinInt16Val(val int16, vals ...int16) int16 { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v < res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ClampInt16 returns a value restricted between lo and hi. | 
					
						
							|  |  |  |  | func ClampInt16(v, lo, hi int16) int16 { | 
					
						
							|  |  |  |  | 	return MinInt16(MaxInt16(v, lo), hi) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxUint32 returns the larger of a and b. | 
					
						
							|  |  |  |  | func MaxUint32(a, b uint32) uint32 { | 
					
						
							|  |  |  |  | 	if a > b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinUint32 returns the smaller of a and b. | 
					
						
							|  |  |  |  | func MinUint32(a, b uint32) uint32 { | 
					
						
							|  |  |  |  | 	if a < b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxUint32Ptr returns a pointer to the larger of a and b, or nil. | 
					
						
							|  |  |  |  | func MaxUint32Ptr(a, b *uint32) *uint32 { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a > *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinUint32Ptr returns a pointer to the smaller of a and b, or nil. | 
					
						
							|  |  |  |  | func MinUint32Ptr(a, b *uint32) *uint32 { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a < *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxUint32Val returns the largest argument passed. | 
					
						
							|  |  |  |  | func MaxUint32Val(val uint32, vals ...uint32) uint32 { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v > res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinUint32Val returns the smallest argument passed. | 
					
						
							|  |  |  |  | func MinUint32Val(val uint32, vals ...uint32) uint32 { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v < res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ClampUint32 returns a value restricted between lo and hi. | 
					
						
							|  |  |  |  | func ClampUint32(v, lo, hi uint32) uint32 { | 
					
						
							|  |  |  |  | 	return MinUint32(MaxUint32(v, lo), hi) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxInt32 returns the larger of a and b. | 
					
						
							|  |  |  |  | func MaxInt32(a, b int32) int32 { | 
					
						
							|  |  |  |  | 	if a > b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinInt32 returns the smaller of a and b. | 
					
						
							|  |  |  |  | func MinInt32(a, b int32) int32 { | 
					
						
							|  |  |  |  | 	if a < b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxInt32Ptr returns a pointer to the larger of a and b, or nil. | 
					
						
							|  |  |  |  | func MaxInt32Ptr(a, b *int32) *int32 { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a > *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinInt32Ptr returns a pointer to the smaller of a and b, or nil. | 
					
						
							|  |  |  |  | func MinInt32Ptr(a, b *int32) *int32 { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a < *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxInt32Val returns the largest argument passed. | 
					
						
							|  |  |  |  | func MaxInt32Val(val int32, vals ...int32) int32 { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v > res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinInt32Val returns the smallest argument passed. | 
					
						
							|  |  |  |  | func MinInt32Val(val int32, vals ...int32) int32 { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v < res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ClampInt32 returns a value restricted between lo and hi. | 
					
						
							|  |  |  |  | func ClampInt32(v, lo, hi int32) int32 { | 
					
						
							|  |  |  |  | 	return MinInt32(MaxInt32(v, lo), hi) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxUint64 returns the larger of a and b. | 
					
						
							|  |  |  |  | func MaxUint64(a, b uint64) uint64 { | 
					
						
							|  |  |  |  | 	if a > b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinUint64 returns the smaller of a and b. | 
					
						
							|  |  |  |  | func MinUint64(a, b uint64) uint64 { | 
					
						
							|  |  |  |  | 	if a < b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxUint64Ptr returns a pointer to the larger of a and b, or nil. | 
					
						
							|  |  |  |  | func MaxUint64Ptr(a, b *uint64) *uint64 { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a > *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinUint64Ptr returns a pointer to the smaller of a and b, or nil. | 
					
						
							|  |  |  |  | func MinUint64Ptr(a, b *uint64) *uint64 { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a < *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxUint64Val returns the largest argument passed. | 
					
						
							|  |  |  |  | func MaxUint64Val(val uint64, vals ...uint64) uint64 { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v > res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinUint64Val returns the smallest argument passed. | 
					
						
							|  |  |  |  | func MinUint64Val(val uint64, vals ...uint64) uint64 { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v < res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ClampUint64 returns a value restricted between lo and hi. | 
					
						
							|  |  |  |  | func ClampUint64(v, lo, hi uint64) uint64 { | 
					
						
							|  |  |  |  | 	return MinUint64(MaxUint64(v, lo), hi) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxInt64 returns the larger of a and b. | 
					
						
							|  |  |  |  | func MaxInt64(a, b int64) int64 { | 
					
						
							|  |  |  |  | 	if a > b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinInt64 returns the smaller of a and b. | 
					
						
							|  |  |  |  | func MinInt64(a, b int64) int64 { | 
					
						
							|  |  |  |  | 	if a < b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxInt64Ptr returns a pointer to the larger of a and b, or nil. | 
					
						
							|  |  |  |  | func MaxInt64Ptr(a, b *int64) *int64 { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a > *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinInt64Ptr returns a pointer to the smaller of a and b, or nil. | 
					
						
							|  |  |  |  | func MinInt64Ptr(a, b *int64) *int64 { | 
					
						
							|  |  |  |  | 	if a == nil { | 
					
						
							|  |  |  |  | 		return b | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if b == nil { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if *a < *b { | 
					
						
							|  |  |  |  | 		return a | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MaxInt64Val returns the largest argument passed. | 
					
						
							|  |  |  |  | func MaxInt64Val(val int64, vals ...int64) int64 { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v > res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MinInt64Val returns the smallest argument passed. | 
					
						
							|  |  |  |  | func MinInt64Val(val int64, vals ...int64) int64 { | 
					
						
							|  |  |  |  | 	res := val | 
					
						
							|  |  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  |  | 		if v < res { | 
					
						
							|  |  |  |  | 			res = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return res | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ClampInt64 returns a value restricted between lo and hi. | 
					
						
							|  |  |  |  | func ClampInt64(v, lo, hi int64) int64 { | 
					
						
							|  |  |  |  | 	return MinInt64(MaxInt64(v, lo), hi) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ToBase produces n in base b. For example | 
					
						
							|  |  |  |  | // | 
					
						
							| 
									
										
										
										
											2025-02-14 16:54:10 +00:00
										 |  |  |  | //	ToBase(2047, 22) -> [1, 5, 4] | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  |  | // | 
					
						
							|  |  |  |  | //	1 * 22^0           1 | 
					
						
							|  |  |  |  | //	5 * 22^1         110 | 
					
						
							|  |  |  |  | //	4 * 22^2        1936 | 
					
						
							|  |  |  |  | //	                ---- | 
					
						
							|  |  |  |  | //	                2047 | 
					
						
							|  |  |  |  | // | 
					
						
							|  |  |  |  | // ToBase panics for bases < 2. | 
					
						
							|  |  |  |  | func ToBase(n *big.Int, b int) []int { | 
					
						
							|  |  |  |  | 	var nn big.Int | 
					
						
							|  |  |  |  | 	nn.Set(n) | 
					
						
							|  |  |  |  | 	if b < 2 { | 
					
						
							|  |  |  |  | 		panic("invalid base") | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	k := 1 | 
					
						
							|  |  |  |  | 	switch nn.Sign() { | 
					
						
							|  |  |  |  | 	case -1: | 
					
						
							|  |  |  |  | 		nn.Neg(&nn) | 
					
						
							|  |  |  |  | 		k = -1 | 
					
						
							|  |  |  |  | 	case 0: | 
					
						
							|  |  |  |  | 		return []int{0} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	bb := big.NewInt(int64(b)) | 
					
						
							|  |  |  |  | 	var r []int | 
					
						
							|  |  |  |  | 	rem := big.NewInt(0) | 
					
						
							|  |  |  |  | 	for nn.Sign() != 0 { | 
					
						
							|  |  |  |  | 		nn.QuoRem(&nn, bb, rem) | 
					
						
							|  |  |  |  | 		r = append(r, k*int(rem.Int64())) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return r | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // CheckAddInt64 returns the a+b and an indicator that the result is greater | 
					
						
							|  |  |  |  | // than math.MaxInt64. | 
					
						
							|  |  |  |  | func CheckAddInt64(a, b int64) (sum int64, gt bool) { | 
					
						
							|  |  |  |  | 	return a + b, a > 0 && b > math.MaxInt64-a || a < 0 && b < math.MinInt64-a | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // CheckSubInt64 returns a-b and an indicator that the result is less than than | 
					
						
							|  |  |  |  | // math.MinInt64. | 
					
						
							|  |  |  |  | func CheckSubInt64(a, b int64) (sum int64, lt bool) { | 
					
						
							|  |  |  |  | 	return a - b, a > 0 && a-math.MaxInt64 > b || a < 0 && a-math.MinInt64 < b | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // AddOverflowInt8 returns a + b and an indication whether the addition | 
					
						
							|  |  |  |  | // overflowed the int8 range. | 
					
						
							|  |  |  |  | func AddOverflowInt8(a, b int8) (r int8, ovf bool) { | 
					
						
							|  |  |  |  | 	r = a + b | 
					
						
							|  |  |  |  | 	if a > 0 && b > 0 { | 
					
						
							|  |  |  |  | 		return r, uint8(r) > math.MaxInt8 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if a < 0 && b < 0 { | 
					
						
							|  |  |  |  | 		return r, uint8(r) <= math.MaxInt8 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return r, false | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // AddOverflowInt16 returns a + b and an indication whether the addition | 
					
						
							|  |  |  |  | // overflowed the int16 range. | 
					
						
							|  |  |  |  | func AddOverflowInt16(a, b int16) (r int16, ovf bool) { | 
					
						
							|  |  |  |  | 	r = a + b | 
					
						
							|  |  |  |  | 	if a > 0 && b > 0 { | 
					
						
							|  |  |  |  | 		return r, uint16(r) > math.MaxInt16 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if a < 0 && b < 0 { | 
					
						
							|  |  |  |  | 		return r, uint16(r) <= math.MaxInt16 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return r, false | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // AddOverflowInt32 returns a + b and an indication whether the addition | 
					
						
							|  |  |  |  | // overflowed the int32 range. | 
					
						
							|  |  |  |  | func AddOverflowInt32(a, b int32) (r int32, ovf bool) { | 
					
						
							|  |  |  |  | 	r = a + b | 
					
						
							|  |  |  |  | 	if a > 0 && b > 0 { | 
					
						
							|  |  |  |  | 		return r, uint32(r) > math.MaxInt32 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if a < 0 && b < 0 { | 
					
						
							|  |  |  |  | 		return r, uint32(r) <= math.MaxInt32 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return r, false | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // AddOverflowInt64 returns a + b and an indication whether the addition | 
					
						
							|  |  |  |  | // overflowed the int64 range. | 
					
						
							|  |  |  |  | func AddOverflowInt64(a, b int64) (r int64, ovf bool) { | 
					
						
							|  |  |  |  | 	r = a + b | 
					
						
							|  |  |  |  | 	if a > 0 && b > 0 { | 
					
						
							|  |  |  |  | 		return r, uint64(r) > math.MaxInt64 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if a < 0 && b < 0 { | 
					
						
							|  |  |  |  | 		return r, uint64(r) <= math.MaxInt64 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return r, false | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // SubOverflowInt8 returns a - b and an indication whether the subtraction | 
					
						
							|  |  |  |  | // overflowed the int8 range. | 
					
						
							|  |  |  |  | func SubOverflowInt8(a, b int8) (r int8, ovf bool) { | 
					
						
							|  |  |  |  | 	r = a - b | 
					
						
							|  |  |  |  | 	if a >= 0 && b < 0 { | 
					
						
							|  |  |  |  | 		return r, uint8(r) >= math.MaxInt8+1 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if a < 0 && b > 0 { | 
					
						
							|  |  |  |  | 		return r, uint8(r) <= math.MaxInt8 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return r, false | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // SubOverflowInt16 returns a - b and an indication whether the subtraction | 
					
						
							|  |  |  |  | // overflowed the int16 range. | 
					
						
							|  |  |  |  | func SubOverflowInt16(a, b int16) (r int16, ovf bool) { | 
					
						
							|  |  |  |  | 	r = a - b | 
					
						
							|  |  |  |  | 	if a >= 0 && b < 0 { | 
					
						
							|  |  |  |  | 		return r, uint16(r) >= math.MaxInt16+1 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if a < 0 && b > 0 { | 
					
						
							|  |  |  |  | 		return r, uint16(r) <= math.MaxInt16 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return r, false | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // SubOverflowInt32 returns a - b and an indication whether the subtraction | 
					
						
							|  |  |  |  | // overflowed the int32 range. | 
					
						
							|  |  |  |  | func SubOverflowInt32(a, b int32) (r int32, ovf bool) { | 
					
						
							|  |  |  |  | 	r = a - b | 
					
						
							|  |  |  |  | 	if a >= 0 && b < 0 { | 
					
						
							|  |  |  |  | 		return r, uint32(r) >= math.MaxInt32+1 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if a < 0 && b > 0 { | 
					
						
							|  |  |  |  | 		return r, uint32(r) <= math.MaxInt32 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return r, false | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // SubOverflowInt64 returns a - b and an indication whether the subtraction | 
					
						
							|  |  |  |  | // overflowed the int64 range. | 
					
						
							|  |  |  |  | func SubOverflowInt64(a, b int64) (r int64, ovf bool) { | 
					
						
							|  |  |  |  | 	r = a - b | 
					
						
							|  |  |  |  | 	if a >= 0 && b < 0 { | 
					
						
							|  |  |  |  | 		return r, uint64(r) >= math.MaxInt64+1 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if a < 0 && b > 0 { | 
					
						
							|  |  |  |  | 		return r, uint64(r) <= math.MaxInt64 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return r, false | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MulOverflowInt8 returns a * b and an indication whether the product | 
					
						
							|  |  |  |  | // overflowed the int8 range. | 
					
						
							|  |  |  |  | func MulOverflowInt8(a, b int8) (r int8, ovf bool) { | 
					
						
							|  |  |  |  | 	if a == 0 || b == 0 { | 
					
						
							|  |  |  |  | 		return 0, false | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	z := int16(a) * int16(b) | 
					
						
							|  |  |  |  | 	return int8(z), z < math.MinInt8 || z > math.MaxInt8 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MulOverflowInt16 returns a * b and an indication whether the product | 
					
						
							|  |  |  |  | // overflowed the int16 range. | 
					
						
							|  |  |  |  | func MulOverflowInt16(a, b int16) (r int16, ovf bool) { | 
					
						
							|  |  |  |  | 	if a == 0 || b == 0 { | 
					
						
							|  |  |  |  | 		return 0, false | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	z := int32(a) * int32(b) | 
					
						
							|  |  |  |  | 	return int16(z), z < math.MinInt16 || z > math.MaxInt16 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MulOverflowInt32 returns a * b and an indication whether the product | 
					
						
							|  |  |  |  | // overflowed the int32 range. | 
					
						
							|  |  |  |  | func MulOverflowInt32(a, b int32) (r int32, ovf bool) { | 
					
						
							|  |  |  |  | 	if a == 0 || b == 0 { | 
					
						
							|  |  |  |  | 		return 0, false | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	z := int64(a) * int64(b) | 
					
						
							|  |  |  |  | 	return int32(z), z < math.MinInt32 || z > math.MaxInt32 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MulOverflowInt64 returns a * b and an indication whether the product | 
					
						
							|  |  |  |  | // overflowed the int64 range. | 
					
						
							|  |  |  |  | func MulOverflowInt64(a, b int64) (r int64, ovf bool) { | 
					
						
							|  |  |  |  | 	// https://groups.google.com/g/golang-nuts/c/h5oSN5t3Au4/m/KaNQREhZh0QJ | 
					
						
							|  |  |  |  | 	const mostPositive = 1<<63 - 1 | 
					
						
							|  |  |  |  | 	const mostNegative = -(mostPositive + 1) | 
					
						
							|  |  |  |  | 	r = a * b | 
					
						
							|  |  |  |  | 	if a == 0 || b == 0 || a == 1 || b == 1 { | 
					
						
							|  |  |  |  | 		return r, false | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if a == mostNegative || b == mostNegative { | 
					
						
							|  |  |  |  | 		return r, true | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	return r, r/b != a | 
					
						
							|  |  |  |  | } |