code.vegaprotocol.io/vega@v0.79.0/libs/num/compare.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package num 17 18 type Signed interface { 19 ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~float32 | ~float64 20 } 21 22 type Unsigned interface { 23 ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 24 } 25 26 type Num interface { 27 Signed | Unsigned 28 } 29 30 // MaxV generic max of any numeric values. 31 func MaxV[T Num](a, b T) T { 32 if a > b { 33 return a 34 } 35 return b 36 } 37 38 // MinV generic min of numneric values. 39 func MinV[T Num](a, b T) T { 40 if a > b { 41 return b 42 } 43 return a 44 } 45 46 // AbsV generic absolute value function of signed primitives. 47 func AbsV[T Signed](a T) T { 48 var b T // get the nil value 49 if a < b { 50 return -a 51 } 52 return a 53 } 54 55 // DeltaV generic delta function signed primitives. 56 func DeltaV[T Signed](a, b T) T { 57 if a < b { 58 return b - a 59 } 60 return a - b 61 } 62 63 // MaxAbs - get max value based on absolute values of abolute vals. 64 func MaxAbs[T Signed](vals ...T) T { 65 var r, m T 66 for _, v := range vals { 67 av := v 68 if av < 0 { 69 av *= -1 70 } 71 if av > m { 72 r = v 73 m = av // current max abs is av 74 } 75 } 76 return r 77 } 78 79 // CmpV compares 2 numeric values of any type, we attempt to cast T1 to T2 and back to see if that conversion 80 // loses any information, if no data is lost this way, we compare both values as T2, otherwise we compare both as T1. 81 func CmpV[T1 Num, T2 Num](a T1, b T2) bool { 82 if a2 := T2(a); a == T1(a2) { 83 // cast to T2 can be cast back to T1 -> no information is lost, and so T2(a) can be safely compared to b 84 return a2 == b 85 } 86 // information was lost in T2(a), either a is float and b is int, or b is float32 vs a float64 87 // either way T1(b) is safe 88 return a == T1(b) 89 }