git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/validate/numerics.go (about)

     1  package validate
     2  
     3  import (
     4  	"math"
     5  )
     6  
     7  // Abs returns absolute value of number
     8  func Abs(value float64) float64 {
     9  	return math.Abs(value)
    10  }
    11  
    12  // Sign returns signum of number: 1 in case of value > 0, -1 in case of value < 0, 0 otherwise
    13  func Sign(value float64) float64 {
    14  	if value > 0 {
    15  		return 1
    16  	} else if value < 0 {
    17  		return -1
    18  	} else {
    19  		return 0
    20  	}
    21  }
    22  
    23  // IsNegative returns true if value < 0
    24  func IsNegative(value float64) bool {
    25  	return value < 0
    26  }
    27  
    28  // IsPositive returns true if value > 0
    29  func IsPositive(value float64) bool {
    30  	return value > 0
    31  }
    32  
    33  // IsNonNegative returns true if value >= 0
    34  func IsNonNegative(value float64) bool {
    35  	return value >= 0
    36  }
    37  
    38  // IsNonPositive returns true if value <= 0
    39  func IsNonPositive(value float64) bool {
    40  	return value <= 0
    41  }
    42  
    43  // InRangeInt returns true if value lies between left and right border
    44  func InRangeInt(value, left, right interface{}) bool {
    45  	value64, _ := ToInt(value)
    46  	left64, _ := ToInt(left)
    47  	right64, _ := ToInt(right)
    48  	if left64 > right64 {
    49  		left64, right64 = right64, left64
    50  	}
    51  	return value64 >= left64 && value64 <= right64
    52  }
    53  
    54  // InRangeFloat32 returns true if value lies between left and right border
    55  func InRangeFloat32(value, left, right float32) bool {
    56  	if left > right {
    57  		left, right = right, left
    58  	}
    59  	return value >= left && value <= right
    60  }
    61  
    62  // InRangeFloat64 returns true if value lies between left and right border
    63  func InRangeFloat64(value, left, right float64) bool {
    64  	if left > right {
    65  		left, right = right, left
    66  	}
    67  	return value >= left && value <= right
    68  }
    69  
    70  // InRange returns true if value lies between left and right border, generic type to handle int, float32, float64 and string.
    71  // All types must the same type.
    72  // False if value doesn't lie in range or if it incompatible or not comparable
    73  func InRange(value interface{}, left interface{}, right interface{}) bool {
    74  	switch value.(type) {
    75  	case int:
    76  		intValue, _ := ToInt(value)
    77  		intLeft, _ := ToInt(left)
    78  		intRight, _ := ToInt(right)
    79  		return InRangeInt(intValue, intLeft, intRight)
    80  	case float32, float64:
    81  		intValue, _ := ToFloat(value)
    82  		intLeft, _ := ToFloat(left)
    83  		intRight, _ := ToFloat(right)
    84  		return InRangeFloat64(intValue, intLeft, intRight)
    85  	case string:
    86  		return value.(string) >= left.(string) && value.(string) <= right.(string)
    87  	default:
    88  		return false
    89  	}
    90  }
    91  
    92  // IsWhole returns true if value is whole number
    93  func IsWhole(value float64) bool {
    94  	return math.Remainder(value, 1) == 0
    95  }
    96  
    97  // IsNatural returns true if value is natural number (positive and whole)
    98  func IsNatural(value float64) bool {
    99  	return IsWhole(value) && IsPositive(value)
   100  }