source: code/trunk/vendor/modernc.org/mathutil/mathutil.go@ 822

Last change on this file since 822 was 822, checked in by yakumo.izuru, 22 months ago

Prefer immortal.run over runit and rc.d, use vendored modules
for convenience.

Signed-off-by: Izuru Yakumo <yakumo.izuru@…>

File size: 30.0 KB
RevLine 
[822]1// Copyright (c) 2014 The mathutil Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package mathutil provides utilities supplementing the standard 'math' and
6// 'math/rand' packages.
7//
8// Release history and compatibility issues
9//
10// 2020-12-20 v1.2.1 fixes MulOverflowInt64.
11//
12// 2020-12-19 Added {Add,Sub,Mul}OverflowInt{8,16,32,64}
13//
14// 2018-10-21 Added BinaryLog
15//
16// 2018-04-25: New functions for determining Max/Min of nullable values. Ex:
17// func MaxPtr(a, b *int) *int {
18// func MinPtr(a, b *int) *int {
19// func MaxBytePtr(a, b *byte) *byte {
20// func MinBytePtr(a, b *byte) *byte {
21// ...
22//
23// 2017-10-14: New variadic functions for Max/Min. Ex:
24// func MaxVal(val int, vals ...int) int {
25// func MinVal(val int, vals ...int) int {
26// func MaxByteVal(val byte, vals ...byte) byte {
27// func MinByteVal(val byte, vals ...byte) byte {
28// ...
29//
30// 2016-10-10: New functions QuadPolyDiscriminant and QuadPolyFactors.
31//
32// 2013-12-13: The following functions have been REMOVED
33//
34// func Uint64ToBigInt(n uint64) *big.Int
35// func Uint64FromBigInt(n *big.Int) (uint64, bool)
36//
37// 2013-05-13: The following functions are now DEPRECATED
38//
39// func Uint64ToBigInt(n uint64) *big.Int
40// func Uint64FromBigInt(n *big.Int) (uint64, bool)
41//
42// These functions will be REMOVED with Go release 1.1+1.
43//
44// 2013-01-21: The following functions have been REMOVED
45//
46// func MaxInt() int
47// func MinInt() int
48// func MaxUint() uint
49// func UintPtrBits() int
50//
51// They are now replaced by untyped constants
52//
53// MaxInt
54// MinInt
55// MaxUint
56// UintPtrBits
57//
58// Additionally one more untyped constant was added
59//
60// IntBits
61//
62// This change breaks any existing code depending on the above removed
63// functions. They should have not been published in the first place, that was
64// unfortunate. Instead, defining such architecture and/or implementation
65// specific integer limits and bit widths as untyped constants improves
66// performance and allows for static dead code elimination if it depends on
67// these values. Thanks to minux for pointing it out in the mail list
68// (https://groups.google.com/d/msg/golang-nuts/tlPpLW6aJw8/NT3mpToH-a4J).
69//
70// 2012-12-12: The following functions will be DEPRECATED with Go release
71// 1.0.3+1 and REMOVED with Go release 1.0.3+2, b/c of
72// http://code.google.com/p/go/source/detail?r=954a79ee3ea8
73//
74// func Uint64ToBigInt(n uint64) *big.Int
75// func Uint64FromBigInt(n *big.Int) (uint64, bool)
76package mathutil // import "modernc.org/mathutil"
77
78import (
79 "math"
80 "math/big"
81)
82
83// Architecture and/or implementation specific integer limits and bit widths.
84const (
85 MaxInt = 1<<(IntBits-1) - 1
86 MinInt = -MaxInt - 1
87 MaxUint = 1<<IntBits - 1
88 IntBits = 1 << (^uint(0)>>32&1 + ^uint(0)>>16&1 + ^uint(0)>>8&1 + 3)
89 UintPtrBits = 1 << (^uintptr(0)>>32&1 + ^uintptr(0)>>16&1 + ^uintptr(0)>>8&1 + 3)
90)
91
92var (
93 _1 = big.NewInt(1)
94 _2 = big.NewInt(2)
95)
96
97// GCDByte returns the greatest common divisor of a and b. Based on:
98// http://en.wikipedia.org/wiki/Euclidean_algorithm#Implementations
99func GCDByte(a, b byte) byte {
100 for b != 0 {
101 a, b = b, a%b
102 }
103 return a
104}
105
106// GCDUint16 returns the greatest common divisor of a and b.
107func GCDUint16(a, b uint16) uint16 {
108 for b != 0 {
109 a, b = b, a%b
110 }
111 return a
112}
113
114// GCDUint32 returns the greatest common divisor of a and b.
115func GCDUint32(a, b uint32) uint32 {
116 for b != 0 {
117 a, b = b, a%b
118 }
119 return a
120}
121
122// GCDUint64 returns the greatest common divisor of a and b.
123func GCDUint64(a, b uint64) uint64 {
124 for b != 0 {
125 a, b = b, a%b
126 }
127 return a
128}
129
130// ISqrt returns floor(sqrt(n)). Typical run time is few hundreds of ns.
131func ISqrt(n uint32) (x uint32) {
132 if n == 0 {
133 return
134 }
135
136 if n >= math.MaxUint16*math.MaxUint16 {
137 return math.MaxUint16
138 }
139
140 var px, nx uint32
141 for x = n; ; px, x = x, nx {
142 nx = (x + n/x) / 2
143 if nx == x || nx == px {
144 break
145 }
146 }
147 return
148}
149
150// SqrtUint64 returns floor(sqrt(n)). Typical run time is about 0.5 µs.
151func SqrtUint64(n uint64) (x uint64) {
152 if n == 0 {
153 return
154 }
155
156 if n >= math.MaxUint32*math.MaxUint32 {
157 return math.MaxUint32
158 }
159
160 var px, nx uint64
161 for x = n; ; px, x = x, nx {
162 nx = (x + n/x) / 2
163 if nx == x || nx == px {
164 break
165 }
166 }
167 return
168}
169
170// SqrtBig returns floor(sqrt(n)). It panics on n < 0.
171func SqrtBig(n *big.Int) (x *big.Int) {
172 switch n.Sign() {
173 case -1:
174 panic(-1)
175 case 0:
176 return big.NewInt(0)
177 }
178
179 var px, nx big.Int
180 x = big.NewInt(0)
181 x.SetBit(x, n.BitLen()/2+1, 1)
182 for {
183 nx.Rsh(nx.Add(x, nx.Div(n, x)), 1)
184 if nx.Cmp(x) == 0 || nx.Cmp(&px) == 0 {
185 break
186 }
187 px.Set(x)
188 x.Set(&nx)
189 }
190 return
191}
192
193// Log2Byte returns log base 2 of n. It's the same as index of the highest
194// bit set in n. For n == 0 -1 is returned.
195func Log2Byte(n byte) int {
196 return log2[n]
197}
198
199// Log2Uint16 returns log base 2 of n. It's the same as index of the highest
200// bit set in n. For n == 0 -1 is returned.
201func Log2Uint16(n uint16) int {
202 if b := n >> 8; b != 0 {
203 return log2[b] + 8
204 }
205
206 return log2[n]
207}
208
209// Log2Uint32 returns log base 2 of n. It's the same as index of the highest
210// bit set in n. For n == 0 -1 is returned.
211func Log2Uint32(n uint32) int {
212 if b := n >> 24; b != 0 {
213 return log2[b] + 24
214 }
215
216 if b := n >> 16; b != 0 {
217 return log2[b] + 16
218 }
219
220 if b := n >> 8; b != 0 {
221 return log2[b] + 8
222 }
223
224 return log2[n]
225}
226
227// Log2Uint64 returns log base 2 of n. It's the same as index of the highest
228// bit set in n. For n == 0 -1 is returned.
229func Log2Uint64(n uint64) int {
230 if b := n >> 56; b != 0 {
231 return log2[b] + 56
232 }
233
234 if b := n >> 48; b != 0 {
235 return log2[b] + 48
236 }
237
238 if b := n >> 40; b != 0 {
239 return log2[b] + 40
240 }
241
242 if b := n >> 32; b != 0 {
243 return log2[b] + 32
244 }
245
246 if b := n >> 24; b != 0 {
247 return log2[b] + 24
248 }
249
250 if b := n >> 16; b != 0 {
251 return log2[b] + 16
252 }
253
254 if b := n >> 8; b != 0 {
255 return log2[b] + 8
256 }
257
258 return log2[n]
259}
260
261// ModPowByte computes (b^e)%m. It panics for m == 0 || b == e == 0.
262//
263// See also: http://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method
264func ModPowByte(b, e, m byte) byte {
265 if b == 0 && e == 0 {
266 panic(0)
267 }
268
269 if m == 1 {
270 return 0
271 }
272
273 r := uint16(1)
274 for b, m := uint16(b), uint16(m); e > 0; b, e = b*b%m, e>>1 {
275 if e&1 == 1 {
276 r = r * b % m
277 }
278 }
279 return byte(r)
280}
281
282// ModPowUint16 computes (b^e)%m. It panics for m == 0 || b == e == 0.
283func ModPowUint16(b, e, m uint16) uint16 {
284 if b == 0 && e == 0 {
285 panic(0)
286 }
287
288 if m == 1 {
289 return 0
290 }
291
292 r := uint32(1)
293 for b, m := uint32(b), uint32(m); e > 0; b, e = b*b%m, e>>1 {
294 if e&1 == 1 {
295 r = r * b % m
296 }
297 }
298 return uint16(r)
299}
300
301// ModPowUint32 computes (b^e)%m. It panics for m == 0 || b == e == 0.
302func ModPowUint32(b, e, m uint32) uint32 {
303 if b == 0 && e == 0 {
304 panic(0)
305 }
306
307 if m == 1 {
308 return 0
309 }
310
311 r := uint64(1)
312 for b, m := uint64(b), uint64(m); e > 0; b, e = b*b%m, e>>1 {
313 if e&1 == 1 {
314 r = r * b % m
315 }
316 }
317 return uint32(r)
318}
319
320// ModPowUint64 computes (b^e)%m. It panics for m == 0 || b == e == 0.
321func ModPowUint64(b, e, m uint64) (r uint64) {
322 if b == 0 && e == 0 {
323 panic(0)
324 }
325
326 if m == 1 {
327 return 0
328 }
329
330 return modPowBigInt(big.NewInt(0).SetUint64(b), big.NewInt(0).SetUint64(e), big.NewInt(0).SetUint64(m)).Uint64()
331}
332
333func modPowBigInt(b, e, m *big.Int) (r *big.Int) {
334 r = big.NewInt(1)
335 for i, n := 0, e.BitLen(); i < n; i++ {
336 if e.Bit(i) != 0 {
337 r.Mod(r.Mul(r, b), m)
338 }
339 b.Mod(b.Mul(b, b), m)
340 }
341 return
342}
343
344// ModPowBigInt computes (b^e)%m. Returns nil for e < 0. It panics for m == 0 || b == e == 0.
345func ModPowBigInt(b, e, m *big.Int) (r *big.Int) {
346 if b.Sign() == 0 && e.Sign() == 0 {
347 panic(0)
348 }
349
350 if m.Cmp(_1) == 0 {
351 return big.NewInt(0)
352 }
353
354 if e.Sign() < 0 {
355 return
356 }
357
358 return modPowBigInt(big.NewInt(0).Set(b), big.NewInt(0).Set(e), m)
359}
360
361var uint64ToBigIntDelta big.Int
362
363func init() {
364 uint64ToBigIntDelta.SetBit(&uint64ToBigIntDelta, 63, 1)
365}
366
367var uintptrBits int
368
369func init() {
370 x := uint64(math.MaxUint64)
371 uintptrBits = BitLenUintptr(uintptr(x))
372}
373
374// UintptrBits returns the bit width of an uintptr at the executing machine.
375func UintptrBits() int {
376 return uintptrBits
377}
378
379// AddUint128_64 returns the uint128 sum of uint64 a and b.
380func AddUint128_64(a, b uint64) (hi uint64, lo uint64) {
381 lo = a + b
382 if lo < a {
383 hi = 1
384 }
385 return hi, lo
386}
387
388// MulUint128_64 returns the uint128 bit product of uint64 a and b.
389func MulUint128_64(a, b uint64) (hi, lo uint64) {
390 /*
391 2^(2 W) ahi bhi + 2^W alo bhi + 2^W ahi blo + alo blo
392
393 FEDCBA98 76543210 FEDCBA98 76543210
394 ---- alo*blo ----
395 ---- alo*bhi ----
396 ---- ahi*blo ----
397 ---- ahi*bhi ----
398 */
399 const w = 32
400 const m = 1<<w - 1
401 ahi, bhi, alo, blo := a>>w, b>>w, a&m, b&m
402 lo = alo * blo
403 mid1 := alo * bhi
404 mid2 := ahi * blo
405 c1, lo := AddUint128_64(lo, mid1<<w)
406 c2, lo := AddUint128_64(lo, mid2<<w)
407 _, hi = AddUint128_64(ahi*bhi, mid1>>w+mid2>>w+c1+c2)
408 return
409}
410
411// PowerizeBigInt returns (e, p) such that e is the smallest number for which p
412// == b^e is greater or equal n. For n < 0 or b < 2 (0, nil) is returned.
413//
414// NOTE: Run time for large values of n (above about 2^1e6 ~= 1e300000) can be
415// significant and/or unacceptabe. For any smaller values of n the function
416// typically performs in sub second time. For "small" values of n (cca bellow
417// 2^1e3 ~= 1e300) the same can be easily below 10 µs.
418//
419// A special (and trivial) case of b == 2 is handled separately and performs
420// much faster.
421func PowerizeBigInt(b, n *big.Int) (e uint32, p *big.Int) {
422 switch {
423 case b.Cmp(_2) < 0 || n.Sign() < 0:
424 return
425 case n.Sign() == 0 || n.Cmp(_1) == 0:
426 return 0, big.NewInt(1)
427 case b.Cmp(_2) == 0:
428 p = big.NewInt(0)
429 e = uint32(n.BitLen() - 1)
430 p.SetBit(p, int(e), 1)
431 if p.Cmp(n) < 0 {
432 p.Mul(p, _2)
433 e++
434 }
435 return
436 }
437
438 bw := b.BitLen()
439 nw := n.BitLen()
440 p = big.NewInt(1)
441 var bb, r big.Int
442 for {
443 switch p.Cmp(n) {
444 case -1:
445 x := uint32((nw - p.BitLen()) / bw)
446 if x == 0 {
447 x = 1
448 }
449 e += x
450 switch x {
451 case 1:
452 p.Mul(p, b)
453 default:
454 r.Set(_1)
455 bb.Set(b)
456 e := x
457 for {
458 if e&1 != 0 {
459 r.Mul(&r, &bb)
460 }
461 if e >>= 1; e == 0 {
462 break
463 }
464
465 bb.Mul(&bb, &bb)
466 }
467 p.Mul(p, &r)
468 }
469 case 0, 1:
470 return
471 }
472 }
473}
474
475// PowerizeUint32BigInt returns (e, p) such that e is the smallest number for
476// which p == b^e is greater or equal n. For n < 0 or b < 2 (0, nil) is
477// returned.
478//
479// More info: see PowerizeBigInt.
480func PowerizeUint32BigInt(b uint32, n *big.Int) (e uint32, p *big.Int) {
481 switch {
482 case b < 2 || n.Sign() < 0:
483 return
484 case n.Sign() == 0 || n.Cmp(_1) == 0:
485 return 0, big.NewInt(1)
486 case b == 2:
487 p = big.NewInt(0)
488 e = uint32(n.BitLen() - 1)
489 p.SetBit(p, int(e), 1)
490 if p.Cmp(n) < 0 {
491 p.Mul(p, _2)
492 e++
493 }
494 return
495 }
496
497 var bb big.Int
498 bb.SetInt64(int64(b))
499 return PowerizeBigInt(&bb, n)
500}
501
502/*
503ProbablyPrimeUint32 returns true if n is prime or n is a pseudoprime to base a.
504It implements the Miller-Rabin primality test for one specific value of 'a' and
505k == 1.
506
507Wrt pseudocode shown at
508http://en.wikipedia.org/wiki/Miller-Rabin_primality_test#Algorithm_and_running_time
509
510 Input: n > 3, an odd integer to be tested for primality;
511 Input: k, a parameter that determines the accuracy of the test
512 Output: composite if n is composite, otherwise probably prime
513 write n − 1 as 2^s·d with d odd by factoring powers of 2 from n − 1
514 LOOP: repeat k times:
515 pick a random integer a in the range [2, n − 2]
516 x ← a^d mod n
517 if x = 1 or x = n − 1 then do next LOOP
518 for r = 1 .. s − 1
519 x ← x^2 mod n
520 if x = 1 then return composite
521 if x = n − 1 then do next LOOP
522 return composite
523 return probably prime
524
525... this function behaves like passing 1 for 'k' and additionally a
526fixed/non-random 'a'. Otherwise it's the same algorithm.
527
528See also: http://mathworld.wolfram.com/Rabin-MillerStrongPseudoprimeTest.html
529*/
530func ProbablyPrimeUint32(n, a uint32) bool {
531 d, s := n-1, 0
532 for ; d&1 == 0; d, s = d>>1, s+1 {
533 }
534 x := uint64(ModPowUint32(a, d, n))
535 if x == 1 || uint32(x) == n-1 {
536 return true
537 }
538
539 for ; s > 1; s-- {
540 if x = x * x % uint64(n); x == 1 {
541 return false
542 }
543
544 if uint32(x) == n-1 {
545 return true
546 }
547 }
548 return false
549}
550
551// ProbablyPrimeUint64_32 returns true if n is prime or n is a pseudoprime to
552// base a. It implements the Miller-Rabin primality test for one specific value
553// of 'a' and k == 1. See also ProbablyPrimeUint32.
554func ProbablyPrimeUint64_32(n uint64, a uint32) bool {
555 d, s := n-1, 0
556 for ; d&1 == 0; d, s = d>>1, s+1 {
557 }
558 x := ModPowUint64(uint64(a), d, n)
559 if x == 1 || x == n-1 {
560 return true
561 }
562
563 bx, bn := big.NewInt(0).SetUint64(x), big.NewInt(0).SetUint64(n)
564 for ; s > 1; s-- {
565 if x = bx.Mod(bx.Mul(bx, bx), bn).Uint64(); x == 1 {
566 return false
567 }
568
569 if x == n-1 {
570 return true
571 }
572 }
573 return false
574}
575
576// ProbablyPrimeBigInt_32 returns true if n is prime or n is a pseudoprime to
577// base a. It implements the Miller-Rabin primality test for one specific value
578// of 'a' and k == 1. See also ProbablyPrimeUint32.
579func ProbablyPrimeBigInt_32(n *big.Int, a uint32) bool {
580 var d big.Int
581 d.Set(n)
582 d.Sub(&d, _1) // d <- n-1
583 s := 0
584 for ; d.Bit(s) == 0; s++ {
585 }
586 nMinus1 := big.NewInt(0).Set(&d)
587 d.Rsh(&d, uint(s))
588
589 x := ModPowBigInt(big.NewInt(int64(a)), &d, n)
590 if x.Cmp(_1) == 0 || x.Cmp(nMinus1) == 0 {
591 return true
592 }
593
594 for ; s > 1; s-- {
595 if x = x.Mod(x.Mul(x, x), n); x.Cmp(_1) == 0 {
596 return false
597 }
598
599 if x.Cmp(nMinus1) == 0 {
600 return true
601 }
602 }
603 return false
604}
605
606// ProbablyPrimeBigInt returns true if n is prime or n is a pseudoprime to base
607// a. It implements the Miller-Rabin primality test for one specific value of
608// 'a' and k == 1. See also ProbablyPrimeUint32.
609func ProbablyPrimeBigInt(n, a *big.Int) bool {
610 var d big.Int
611 d.Set(n)
612 d.Sub(&d, _1) // d <- n-1
613 s := 0
614 for ; d.Bit(s) == 0; s++ {
615 }
616 nMinus1 := big.NewInt(0).Set(&d)
617 d.Rsh(&d, uint(s))
618
619 x := ModPowBigInt(a, &d, n)
620 if x.Cmp(_1) == 0 || x.Cmp(nMinus1) == 0 {
621 return true
622 }
623
624 for ; s > 1; s-- {
625 if x = x.Mod(x.Mul(x, x), n); x.Cmp(_1) == 0 {
626 return false
627 }
628
629 if x.Cmp(nMinus1) == 0 {
630 return true
631 }
632 }
633 return false
634}
635
636// Max returns the larger of a and b.
637func Max(a, b int) int {
638 if a > b {
639 return a
640 }
641
642 return b
643}
644
645// Min returns the smaller of a and b.
646func Min(a, b int) int {
647 if a < b {
648 return a
649 }
650
651 return b
652}
653
654// MaxPtr returns a pointer to the larger of a and b, or nil.
655func MaxPtr(a, b *int) *int {
656 if a == nil {
657 return b
658 }
659 if b == nil {
660 return a
661 }
662 if *a > *b {
663 return a
664 }
665
666 return b
667}
668
669// MinPtr returns a pointer to the smaller of a and b, or nil.
670func MinPtr(a, b *int) *int {
671 if a == nil {
672 return b
673 }
674 if b == nil {
675 return a
676 }
677 if *a < *b {
678 return a
679 }
680
681 return b
682}
683
684// MaxVal returns the largest argument passed.
685func MaxVal(val int, vals ...int) int {
686 res := val
687 for _, v := range vals {
688 if v > res {
689 res = v
690 }
691 }
692 return res
693}
694
695// MinVal returns the smallest argument passed.
696func MinVal(val int, vals ...int) int {
697 res := val
698 for _, v := range vals {
699 if v < res {
700 res = v
701 }
702 }
703 return res
704}
705
706// Clamp returns a value restricted between lo and hi.
707func Clamp(v, lo, hi int) int {
708 return Min(Max(v, lo), hi)
709}
710
711// UMax returns the larger of a and b.
712func UMax(a, b uint) uint {
713 if a > b {
714 return a
715 }
716
717 return b
718}
719
720// UMin returns the smaller of a and b.
721func UMin(a, b uint) uint {
722 if a < b {
723 return a
724 }
725
726 return b
727}
728
729// UMaxPtr returns a pointer to the larger of a and b, or nil.
730func UMaxPtr(a, b *uint) *uint {
731 if a == nil {
732 return b
733 }
734 if b == nil {
735 return a
736 }
737 if *a > *b {
738 return a
739 }
740
741 return b
742}
743
744// UMinPtr returns a pointer to the smaller of a and b, or nil.
745func UMinPtr(a, b *uint) *uint {
746 if a == nil {
747 return b
748 }
749 if b == nil {
750 return a
751 }
752 if *a < *b {
753 return a
754 }
755
756 return b
757}
758
759// UMaxVal returns the largest argument passed.
760func UMaxVal(val uint, vals ...uint) uint {
761 res := val
762 for _, v := range vals {
763 if v > res {
764 res = v
765 }
766 }
767 return res
768}
769
770// UMinVal returns the smallest argument passed.
771func UMinVal(val uint, vals ...uint) uint {
772 res := val
773 for _, v := range vals {
774 if v < res {
775 res = v
776 }
777 }
778 return res
779}
780
781// UClamp returns a value restricted between lo and hi.
782func UClamp(v, lo, hi uint) uint {
783 return UMin(UMax(v, lo), hi)
784}
785
786// MaxByte returns the larger of a and b.
787func MaxByte(a, b byte) byte {
788 if a > b {
789 return a
790 }
791
792 return b
793}
794
795// MinByte returns the smaller of a and b.
796func MinByte(a, b byte) byte {
797 if a < b {
798 return a
799 }
800
801 return b
802}
803
804// MaxBytePtr returns a pointer to the larger of a and b, or nil.
805func MaxBytePtr(a, b *byte) *byte {
806 if a == nil {
807 return b
808 }
809 if b == nil {
810 return a
811 }
812 if *a > *b {
813 return a
814 }
815
816 return b
817}
818
819// MinBytePtr returns a pointer to the smaller of a and b, or nil.
820func MinBytePtr(a, b *byte) *byte {
821 if a == nil {
822 return b
823 }
824 if b == nil {
825 return a
826 }
827 if *a < *b {
828 return a
829 }
830
831 return b
832}
833
834// MaxByteVal returns the largest argument passed.
835func MaxByteVal(val byte, vals ...byte) byte {
836 res := val
837 for _, v := range vals {
838 if v > res {
839 res = v
840 }
841 }
842 return res
843}
844
845// MinByteVal returns the smallest argument passed.
846func MinByteVal(val byte, vals ...byte) byte {
847 res := val
848 for _, v := range vals {
849 if v < res {
850 res = v
851 }
852 }
853 return res
854}
855
856// ClampByte returns a value restricted between lo and hi.
857func ClampByte(v, lo, hi byte) byte {
858 return MinByte(MaxByte(v, lo), hi)
859}
860
861// MaxInt8 returns the larger of a and b.
862func MaxInt8(a, b int8) int8 {
863 if a > b {
864 return a
865 }
866
867 return b
868}
869
870// MinInt8 returns the smaller of a and b.
871func MinInt8(a, b int8) int8 {
872 if a < b {
873 return a
874 }
875
876 return b
877}
878
879// MaxInt8Ptr returns a pointer to the larger of a and b, or nil.
880func MaxInt8Ptr(a, b *int8) *int8 {
881 if a == nil {
882 return b
883 }
884 if b == nil {
885 return a
886 }
887 if *a > *b {
888 return a
889 }
890
891 return b
892}
893
894// MinInt8Ptr returns a pointer to the smaller of a and b, or nil.
895func MinInt8Ptr(a, b *int8) *int8 {
896 if a == nil {
897 return b
898 }
899 if b == nil {
900 return a
901 }
902 if *a < *b {
903 return a
904 }
905
906 return b
907}
908
909// MaxInt8Val returns the largest argument passed.
910func MaxInt8Val(val int8, vals ...int8) int8 {
911 res := val
912 for _, v := range vals {
913 if v > res {
914 res = v
915 }
916 }
917 return res
918}
919
920// MinInt8Val returns the smallest argument passed.
921func MinInt8Val(val int8, vals ...int8) int8 {
922 res := val
923 for _, v := range vals {
924 if v < res {
925 res = v
926 }
927 }
928 return res
929}
930
931// ClampInt8 returns a value restricted between lo and hi.
932func ClampInt8(v, lo, hi int8) int8 {
933 return MinInt8(MaxInt8(v, lo), hi)
934}
935
936// MaxUint16 returns the larger of a and b.
937func MaxUint16(a, b uint16) uint16 {
938 if a > b {
939 return a
940 }
941
942 return b
943}
944
945// MinUint16 returns the smaller of a and b.
946func MinUint16(a, b uint16) uint16 {
947 if a < b {
948 return a
949 }
950
951 return b
952}
953
954// MaxUint16Ptr returns a pointer to the larger of a and b, or nil.
955func MaxUint16Ptr(a, b *uint16) *uint16 {
956 if a == nil {
957 return b
958 }
959 if b == nil {
960 return a
961 }
962 if *a > *b {
963 return a
964 }
965
966 return b
967}
968
969// MinUint16Ptr returns a pointer to the smaller of a and b, or nil.
970func MinUint16Ptr(a, b *uint16) *uint16 {
971 if a == nil {
972 return b
973 }
974 if b == nil {
975 return a
976 }
977 if *a < *b {
978 return a
979 }
980
981 return b
982}
983
984// MaxUint16Val returns the largest argument passed.
985func MaxUint16Val(val uint16, vals ...uint16) uint16 {
986 res := val
987 for _, v := range vals {
988 if v > res {
989 res = v
990 }
991 }
992 return res
993}
994
995// MinUint16Val returns the smallest argument passed.
996func MinUint16Val(val uint16, vals ...uint16) uint16 {
997 res := val
998 for _, v := range vals {
999 if v < res {
1000 res = v
1001 }
1002 }
1003 return res
1004}
1005
1006// ClampUint16 returns a value restricted between lo and hi.
1007func ClampUint16(v, lo, hi uint16) uint16 {
1008 return MinUint16(MaxUint16(v, lo), hi)
1009}
1010
1011// MaxInt16 returns the larger of a and b.
1012func MaxInt16(a, b int16) int16 {
1013 if a > b {
1014 return a
1015 }
1016
1017 return b
1018}
1019
1020// MinInt16 returns the smaller of a and b.
1021func MinInt16(a, b int16) int16 {
1022 if a < b {
1023 return a
1024 }
1025
1026 return b
1027}
1028
1029// MaxInt16Ptr returns a pointer to the larger of a and b, or nil.
1030func MaxInt16Ptr(a, b *int16) *int16 {
1031 if a == nil {
1032 return b
1033 }
1034 if b == nil {
1035 return a
1036 }
1037 if *a > *b {
1038 return a
1039 }
1040
1041 return b
1042}
1043
1044// MinInt16Ptr returns a pointer to the smaller of a and b, or nil.
1045func MinInt16Ptr(a, b *int16) *int16 {
1046 if a == nil {
1047 return b
1048 }
1049 if b == nil {
1050 return a
1051 }
1052 if *a < *b {
1053 return a
1054 }
1055
1056 return b
1057}
1058
1059// MaxInt16Val returns the largest argument passed.
1060func MaxInt16Val(val int16, vals ...int16) int16 {
1061 res := val
1062 for _, v := range vals {
1063 if v > res {
1064 res = v
1065 }
1066 }
1067 return res
1068}
1069
1070// MinInt16Val returns the smallest argument passed.
1071func MinInt16Val(val int16, vals ...int16) int16 {
1072 res := val
1073 for _, v := range vals {
1074 if v < res {
1075 res = v
1076 }
1077 }
1078 return res
1079}
1080
1081// ClampInt16 returns a value restricted between lo and hi.
1082func ClampInt16(v, lo, hi int16) int16 {
1083 return MinInt16(MaxInt16(v, lo), hi)
1084}
1085
1086// MaxUint32 returns the larger of a and b.
1087func MaxUint32(a, b uint32) uint32 {
1088 if a > b {
1089 return a
1090 }
1091
1092 return b
1093}
1094
1095// MinUint32 returns the smaller of a and b.
1096func MinUint32(a, b uint32) uint32 {
1097 if a < b {
1098 return a
1099 }
1100
1101 return b
1102}
1103
1104// MaxUint32Ptr returns a pointer to the larger of a and b, or nil.
1105func MaxUint32Ptr(a, b *uint32) *uint32 {
1106 if a == nil {
1107 return b
1108 }
1109 if b == nil {
1110 return a
1111 }
1112 if *a > *b {
1113 return a
1114 }
1115
1116 return b
1117}
1118
1119// MinUint32Ptr returns a pointer to the smaller of a and b, or nil.
1120func MinUint32Ptr(a, b *uint32) *uint32 {
1121 if a == nil {
1122 return b
1123 }
1124 if b == nil {
1125 return a
1126 }
1127 if *a < *b {
1128 return a
1129 }
1130
1131 return b
1132}
1133
1134// MaxUint32Val returns the largest argument passed.
1135func MaxUint32Val(val uint32, vals ...uint32) uint32 {
1136 res := val
1137 for _, v := range vals {
1138 if v > res {
1139 res = v
1140 }
1141 }
1142 return res
1143}
1144
1145// MinUint32Val returns the smallest argument passed.
1146func MinUint32Val(val uint32, vals ...uint32) uint32 {
1147 res := val
1148 for _, v := range vals {
1149 if v < res {
1150 res = v
1151 }
1152 }
1153 return res
1154}
1155
1156// ClampUint32 returns a value restricted between lo and hi.
1157func ClampUint32(v, lo, hi uint32) uint32 {
1158 return MinUint32(MaxUint32(v, lo), hi)
1159}
1160
1161// MaxInt32 returns the larger of a and b.
1162func MaxInt32(a, b int32) int32 {
1163 if a > b {
1164 return a
1165 }
1166
1167 return b
1168}
1169
1170// MinInt32 returns the smaller of a and b.
1171func MinInt32(a, b int32) int32 {
1172 if a < b {
1173 return a
1174 }
1175
1176 return b
1177}
1178
1179// MaxInt32Ptr returns a pointer to the larger of a and b, or nil.
1180func MaxInt32Ptr(a, b *int32) *int32 {
1181 if a == nil {
1182 return b
1183 }
1184 if b == nil {
1185 return a
1186 }
1187 if *a > *b {
1188 return a
1189 }
1190
1191 return b
1192}
1193
1194// MinInt32Ptr returns a pointer to the smaller of a and b, or nil.
1195func MinInt32Ptr(a, b *int32) *int32 {
1196 if a == nil {
1197 return b
1198 }
1199 if b == nil {
1200 return a
1201 }
1202 if *a < *b {
1203 return a
1204 }
1205
1206 return b
1207}
1208
1209// MaxInt32Val returns the largest argument passed.
1210func MaxInt32Val(val int32, vals ...int32) int32 {
1211 res := val
1212 for _, v := range vals {
1213 if v > res {
1214 res = v
1215 }
1216 }
1217 return res
1218}
1219
1220// MinInt32Val returns the smallest argument passed.
1221func MinInt32Val(val int32, vals ...int32) int32 {
1222 res := val
1223 for _, v := range vals {
1224 if v < res {
1225 res = v
1226 }
1227 }
1228 return res
1229}
1230
1231// ClampInt32 returns a value restricted between lo and hi.
1232func ClampInt32(v, lo, hi int32) int32 {
1233 return MinInt32(MaxInt32(v, lo), hi)
1234}
1235
1236// MaxUint64 returns the larger of a and b.
1237func MaxUint64(a, b uint64) uint64 {
1238 if a > b {
1239 return a
1240 }
1241
1242 return b
1243}
1244
1245// MinUint64 returns the smaller of a and b.
1246func MinUint64(a, b uint64) uint64 {
1247 if a < b {
1248 return a
1249 }
1250
1251 return b
1252}
1253
1254// MaxUint64Ptr returns a pointer to the larger of a and b, or nil.
1255func MaxUint64Ptr(a, b *uint64) *uint64 {
1256 if a == nil {
1257 return b
1258 }
1259 if b == nil {
1260 return a
1261 }
1262 if *a > *b {
1263 return a
1264 }
1265
1266 return b
1267}
1268
1269// MinUint64Ptr returns a pointer to the smaller of a and b, or nil.
1270func MinUint64Ptr(a, b *uint64) *uint64 {
1271 if a == nil {
1272 return b
1273 }
1274 if b == nil {
1275 return a
1276 }
1277 if *a < *b {
1278 return a
1279 }
1280
1281 return b
1282}
1283
1284// MaxUint64Val returns the largest argument passed.
1285func MaxUint64Val(val uint64, vals ...uint64) uint64 {
1286 res := val
1287 for _, v := range vals {
1288 if v > res {
1289 res = v
1290 }
1291 }
1292 return res
1293}
1294
1295// MinUint64Val returns the smallest argument passed.
1296func MinUint64Val(val uint64, vals ...uint64) uint64 {
1297 res := val
1298 for _, v := range vals {
1299 if v < res {
1300 res = v
1301 }
1302 }
1303 return res
1304}
1305
1306// ClampUint64 returns a value restricted between lo and hi.
1307func ClampUint64(v, lo, hi uint64) uint64 {
1308 return MinUint64(MaxUint64(v, lo), hi)
1309}
1310
1311// MaxInt64 returns the larger of a and b.
1312func MaxInt64(a, b int64) int64 {
1313 if a > b {
1314 return a
1315 }
1316
1317 return b
1318}
1319
1320// MinInt64 returns the smaller of a and b.
1321func MinInt64(a, b int64) int64 {
1322 if a < b {
1323 return a
1324 }
1325
1326 return b
1327}
1328
1329// MaxInt64Ptr returns a pointer to the larger of a and b, or nil.
1330func MaxInt64Ptr(a, b *int64) *int64 {
1331 if a == nil {
1332 return b
1333 }
1334 if b == nil {
1335 return a
1336 }
1337 if *a > *b {
1338 return a
1339 }
1340
1341 return b
1342}
1343
1344// MinInt64Ptr returns a pointer to the smaller of a and b, or nil.
1345func MinInt64Ptr(a, b *int64) *int64 {
1346 if a == nil {
1347 return b
1348 }
1349 if b == nil {
1350 return a
1351 }
1352 if *a < *b {
1353 return a
1354 }
1355
1356 return b
1357}
1358
1359// MaxInt64Val returns the largest argument passed.
1360func MaxInt64Val(val int64, vals ...int64) int64 {
1361 res := val
1362 for _, v := range vals {
1363 if v > res {
1364 res = v
1365 }
1366 }
1367 return res
1368}
1369
1370// MinInt64Val returns the smallest argument passed.
1371func MinInt64Val(val int64, vals ...int64) int64 {
1372 res := val
1373 for _, v := range vals {
1374 if v < res {
1375 res = v
1376 }
1377 }
1378 return res
1379}
1380
1381// ClampInt64 returns a value restricted between lo and hi.
1382func ClampInt64(v, lo, hi int64) int64 {
1383 return MinInt64(MaxInt64(v, lo), hi)
1384}
1385
1386// ToBase produces n in base b. For example
1387//
1388// ToBase(2047, 22) -> [1, 5, 4]
1389//
1390// 1 * 22^0 1
1391// 5 * 22^1 110
1392// 4 * 22^2 1936
1393// ----
1394// 2047
1395//
1396// ToBase panics for bases < 2.
1397func ToBase(n *big.Int, b int) []int {
1398 var nn big.Int
1399 nn.Set(n)
1400 if b < 2 {
1401 panic("invalid base")
1402 }
1403
1404 k := 1
1405 switch nn.Sign() {
1406 case -1:
1407 nn.Neg(&nn)
1408 k = -1
1409 case 0:
1410 return []int{0}
1411 }
1412
1413 bb := big.NewInt(int64(b))
1414 var r []int
1415 rem := big.NewInt(0)
1416 for nn.Sign() != 0 {
1417 nn.QuoRem(&nn, bb, rem)
1418 r = append(r, k*int(rem.Int64()))
1419 }
1420 return r
1421}
1422
1423// CheckAddInt64 returns the a+b and an indicator that the result is greater
1424// than math.MaxInt64.
1425func CheckAddInt64(a, b int64) (sum int64, gt bool) {
1426 return a + b, a > 0 && b > math.MaxInt64-a || a < 0 && b < math.MinInt64-a
1427}
1428
1429// CheckSubInt64 returns a-b and an indicator that the result is less than than
1430// math.MinInt64.
1431func CheckSubInt64(a, b int64) (sum int64, lt bool) {
1432 return a - b, a > 0 && a-math.MaxInt64 > b || a < 0 && a-math.MinInt64 < b
1433}
1434
1435// AddOverflowInt8 returns a + b and an indication whether the addition
1436// overflowed the int8 range.
1437func AddOverflowInt8(a, b int8) (r int8, ovf bool) {
1438 r = a + b
1439 if a > 0 && b > 0 {
1440 return r, uint8(r) > math.MaxInt8
1441 }
1442
1443 if a < 0 && b < 0 {
1444 return r, uint8(r) <= math.MaxInt8
1445 }
1446
1447 return r, false
1448}
1449
1450// AddOverflowInt16 returns a + b and an indication whether the addition
1451// overflowed the int16 range.
1452func AddOverflowInt16(a, b int16) (r int16, ovf bool) {
1453 r = a + b
1454 if a > 0 && b > 0 {
1455 return r, uint16(r) > math.MaxInt16
1456 }
1457
1458 if a < 0 && b < 0 {
1459 return r, uint16(r) <= math.MaxInt16
1460 }
1461
1462 return r, false
1463}
1464
1465// AddOverflowInt32 returns a + b and an indication whether the addition
1466// overflowed the int32 range.
1467func AddOverflowInt32(a, b int32) (r int32, ovf bool) {
1468 r = a + b
1469 if a > 0 && b > 0 {
1470 return r, uint32(r) > math.MaxInt32
1471 }
1472
1473 if a < 0 && b < 0 {
1474 return r, uint32(r) <= math.MaxInt32
1475 }
1476
1477 return r, false
1478}
1479
1480// AddOverflowInt64 returns a + b and an indication whether the addition
1481// overflowed the int64 range.
1482func AddOverflowInt64(a, b int64) (r int64, ovf bool) {
1483 r = a + b
1484 if a > 0 && b > 0 {
1485 return r, uint64(r) > math.MaxInt64
1486 }
1487
1488 if a < 0 && b < 0 {
1489 return r, uint64(r) <= math.MaxInt64
1490 }
1491
1492 return r, false
1493}
1494
1495// SubOverflowInt8 returns a - b and an indication whether the subtraction
1496// overflowed the int8 range.
1497func SubOverflowInt8(a, b int8) (r int8, ovf bool) {
1498 r = a - b
1499 if a >= 0 && b < 0 {
1500 return r, uint8(r) >= math.MaxInt8+1
1501 }
1502
1503 if a < 0 && b > 0 {
1504 return r, uint8(r) <= math.MaxInt8
1505 }
1506
1507 return r, false
1508}
1509
1510// SubOverflowInt16 returns a - b and an indication whether the subtraction
1511// overflowed the int16 range.
1512func SubOverflowInt16(a, b int16) (r int16, ovf bool) {
1513 r = a - b
1514 if a >= 0 && b < 0 {
1515 return r, uint16(r) >= math.MaxInt16+1
1516 }
1517
1518 if a < 0 && b > 0 {
1519 return r, uint16(r) <= math.MaxInt16
1520 }
1521
1522 return r, false
1523}
1524
1525// SubOverflowInt32 returns a - b and an indication whether the subtraction
1526// overflowed the int32 range.
1527func SubOverflowInt32(a, b int32) (r int32, ovf bool) {
1528 r = a - b
1529 if a >= 0 && b < 0 {
1530 return r, uint32(r) >= math.MaxInt32+1
1531 }
1532
1533 if a < 0 && b > 0 {
1534 return r, uint32(r) <= math.MaxInt32
1535 }
1536
1537 return r, false
1538}
1539
1540// SubOverflowInt64 returns a - b and an indication whether the subtraction
1541// overflowed the int64 range.
1542func SubOverflowInt64(a, b int64) (r int64, ovf bool) {
1543 r = a - b
1544 if a >= 0 && b < 0 {
1545 return r, uint64(r) >= math.MaxInt64+1
1546 }
1547
1548 if a < 0 && b > 0 {
1549 return r, uint64(r) <= math.MaxInt64
1550 }
1551
1552 return r, false
1553}
1554
1555// MulOverflowInt8 returns a * b and an indication whether the product
1556// overflowed the int8 range.
1557func MulOverflowInt8(a, b int8) (r int8, ovf bool) {
1558 if a == 0 || b == 0 {
1559 return 0, false
1560 }
1561
1562 z := int16(a) * int16(b)
1563 return int8(z), z < math.MinInt8 || z > math.MaxInt8
1564}
1565
1566// MulOverflowInt16 returns a * b and an indication whether the product
1567// overflowed the int16 range.
1568func MulOverflowInt16(a, b int16) (r int16, ovf bool) {
1569 if a == 0 || b == 0 {
1570 return 0, false
1571 }
1572
1573 z := int32(a) * int32(b)
1574 return int16(z), z < math.MinInt16 || z > math.MaxInt16
1575}
1576
1577// MulOverflowInt32 returns a * b and an indication whether the product
1578// overflowed the int32 range.
1579func MulOverflowInt32(a, b int32) (r int32, ovf bool) {
1580 if a == 0 || b == 0 {
1581 return 0, false
1582 }
1583
1584 z := int64(a) * int64(b)
1585 return int32(z), z < math.MinInt32 || z > math.MaxInt32
1586}
1587
1588// MulOverflowInt64 returns a * b and an indication whether the product
1589// overflowed the int64 range.
1590func MulOverflowInt64(a, b int64) (r int64, ovf bool) {
1591 // https://groups.google.com/g/golang-nuts/c/h5oSN5t3Au4/m/KaNQREhZh0QJ
1592 const mostPositive = 1<<63 - 1
1593 const mostNegative = -(mostPositive + 1)
1594 r = a * b
1595 if a == 0 || b == 0 || a == 1 || b == 1 {
1596 return r, false
1597 }
1598
1599 if a == mostNegative || b == mostNegative {
1600 return r, true
1601 }
1602
1603 return r, r/b != a
1604}
Note: See TracBrowser for help on using the repository browser.