gitee.com/quant1x/num@v0.3.2/abs.go (about)

     1  package num
     2  
     3  import (
     4  	"gitee.com/quant1x/num/x32"
     5  	"gitee.com/quant1x/num/x64"
     6  	"math"
     7  )
     8  
     9  // Abs 泛型绝对值
    10  func Abs[T BaseType](x []T) []T {
    11  	var d any
    12  	switch xv := any(x).(type) {
    13  	case []float32:
    14  		d = x32.Abs(xv)
    15  	case []float64:
    16  		d = x64.Abs(xv)
    17  	case []int:
    18  		d = __go_abs(xv)
    19  	case []int8:
    20  		d = __go_abs(xv)
    21  	case []int16:
    22  		d = __go_abs(xv)
    23  	case []int32:
    24  		d = __go_abs(xv)
    25  	case []int64:
    26  		d = __go_abs(xv)
    27  	case []uint, []uint8, []uint16, []uint32, []uint64, []uintptr:
    28  		d = xv
    29  	default:
    30  		// 其它类型原样返回
    31  		d = xv
    32  	}
    33  	return d.([]T)
    34  }
    35  
    36  func __go_abs[T Signed | Float](x []T) []T {
    37  	xLen := len(x)
    38  	d := make([]T, xLen)
    39  	for i := 0; i < xLen; i++ {
    40  		if x[i] < 0 {
    41  			d[i] = -x[i]
    42  		} else {
    43  			d[i] = x[i]
    44  		}
    45  	}
    46  	return d
    47  }
    48  
    49  // AbsInt8 gets absolute value of int8.
    50  //
    51  // Example 1: AbsInt8(-5)
    52  // -5 code value as below
    53  // original code	1000,0101
    54  // inverse code		1111,1010
    55  // complement code	1111,1011
    56  // Negative numbers are represented by complement code in memory.
    57  // shifted = n >> 7 = (1111,1011) >> 7 = 1111,1111 = -1(10-base) (负数右移,左补1)
    58  //
    59  //	1111,1011
    60  //
    61  // n xor shifted =  ----------- = 0000,0100 = 4(10-base)
    62  //
    63  //	1111,1111
    64  //
    65  // (n ^ shifted) - shifted = 4 - (-1) = 5
    66  //
    67  // Example 2: AbsInt8(5)
    68  // 5 code value as below
    69  // original code 0000,0101
    70  // Positive numbers are represented by original code in memory,
    71  // and the XOR operation between positive numbers and 0 is equal to itself.
    72  // shifted = n >> 7 = 0
    73  //
    74  //	0000,0101
    75  //
    76  // n xor shifted =  ----------- = 0000,0101 = 5(10-base)
    77  //
    78  //	0000,0000
    79  //
    80  // (n ^ shifted) - shifted = 5 - 0 = 5
    81  func AbsInt8(n int8) int8 {
    82  	shifted := n >> 7
    83  	return (n ^ shifted) - shifted
    84  }
    85  
    86  // AbsInt16 gets absolute value of int16.
    87  func AbsInt16(n int16) int16 {
    88  	shifted := n >> 15
    89  	return (n ^ shifted) - shifted
    90  }
    91  
    92  // AbsInt32 gets absolute value of int32.
    93  func AbsInt32(n int32) int32 {
    94  	shifted := n >> 31
    95  	return (n ^ shifted) - shifted
    96  }
    97  
    98  // AbsInt64 gets absolute value of int64.
    99  func AbsInt64(n int64) int64 {
   100  	shifted := n >> 63
   101  	return (n ^ shifted) - shifted
   102  }
   103  
   104  // AbsInt gets absolute value of int.
   105  func AbsInt(n int) int {
   106  	shifted := n >> 63
   107  	return (n ^ shifted) - shifted
   108  }
   109  
   110  func AbsFloat32(n float32) float32 {
   111  	return math.Float32frombits(math.Float32bits(n) &^ (1 << 31))
   112  }
   113  
   114  func AbsFloat64(n float64) float64 {
   115  	return math.Abs(n)
   116  }