github.com/vescale/zgraph@v0.0.0-20230410094002-959c02d50f95/internal/mathutil/math.go (about)

     1  // Copyright 2019 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package mathutil
    16  
    17  import (
    18  	"math"
    19  
    20  	"golang.org/x/exp/constraints"
    21  )
    22  
    23  // Architecture and/or implementation specific integer limits and bit widths.
    24  const (
    25  	MaxInt  = 1<<(IntBits-1) - 1
    26  	MinInt  = -MaxInt - 1
    27  	MaxUint = 1<<IntBits - 1
    28  	IntBits = 1 << (^uint(0)>>32&1 + ^uint(0)>>16&1 + ^uint(0)>>8&1 + 3)
    29  )
    30  
    31  // Abs implement the abs function according to http://cavaliercoder.com/blog/optimized-abs-for-int64-in-go.html
    32  func Abs(n int64) int64 {
    33  	y := n >> 63
    34  	return (n ^ y) - y
    35  }
    36  
    37  // uintSizeTable is used as a table to do comparison to get uint length is faster than doing loop on division with 10
    38  var uintSizeTable = [21]uint64{
    39  	0, // redundant 0 here, so to make function StrLenOfUint64Fast to count from 1 and return i directly
    40  	9, 99, 999, 9999, 99999,
    41  	999999, 9999999, 99999999, 999999999, 9999999999,
    42  	99999999999, 999999999999, 9999999999999, 99999999999999, 999999999999999,
    43  	9999999999999999, 99999999999999999, 999999999999999999, 9999999999999999999,
    44  	math.MaxUint64,
    45  } // math.MaxUint64 is 18446744073709551615 and it has 20 digits
    46  
    47  // StrLenOfUint64Fast efficiently calculate the string character lengths of an uint64 as input
    48  func StrLenOfUint64Fast(x uint64) int {
    49  	for i := 1; ; i++ {
    50  		if x <= uintSizeTable[i] {
    51  			return i
    52  		}
    53  	}
    54  }
    55  
    56  // StrLenOfInt64Fast efficiently calculate the string character lengths of an int64 as input
    57  func StrLenOfInt64Fast(x int64) int {
    58  	size := 0
    59  	if x < 0 {
    60  		size = 1 // add "-" sign on the length count
    61  	}
    62  	return size + StrLenOfUint64Fast(uint64(Abs(x)))
    63  }
    64  
    65  // IsFinite reports whether f is neither NaN nor an infinity.
    66  func IsFinite(f float64) bool {
    67  	return !math.IsNaN(f - f)
    68  }
    69  
    70  // Max returns the largest one from its arguments.
    71  func Max[T constraints.Ordered](x T, xs ...T) T {
    72  	max := x
    73  	for _, n := range xs {
    74  		if n > max {
    75  			max = n
    76  		}
    77  	}
    78  	return max
    79  }
    80  
    81  // Min returns the smallest one from its arguments.
    82  func Min[T constraints.Ordered](x T, xs ...T) T {
    83  	min := x
    84  	for _, n := range xs {
    85  		if n < min {
    86  			min = n
    87  		}
    88  	}
    89  	return min
    90  }
    91  
    92  // Clamp restrict a value to a certain interval.
    93  func Clamp[T constraints.Ordered](n, min, max T) T {
    94  	if n >= max {
    95  		return max
    96  	} else if n <= min {
    97  		return min
    98  	}
    99  	return n
   100  }