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  }