github.com/puellanivis/breton@v0.2.16/lib/sort/float.go (about)

     1  package sort
     2  
     3  import (
     4  	"math"
     5  	"sort"
     6  )
     7  
     8  // Float64Slice attaches the methods of sort.Interface to []float64, sorting in increasing order.
     9  type Float64Slice []float64
    10  
    11  // Len implements sort.Interface.
    12  func (p Float64Slice) Len() int { return len(p) }
    13  
    14  // Less implements sort.Interface.
    15  func (p Float64Slice) Less(i, j int) bool { return p[i] < p[j] || isNaN64(p[i]) && !isNaN64(p[j]) }
    16  
    17  // Swap implements sort.Interface.
    18  func (p Float64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
    19  
    20  func cmpFloat64(x, y float64) int {
    21  	if x == y {
    22  		return 0
    23  	}
    24  
    25  	if x < y {
    26  		return -1
    27  	}
    28  
    29  	return +1
    30  }
    31  
    32  // Compare implements Comparer.
    33  func (p Float64Slice) Compare(i, j int) int {
    34  	return cmpFloat64(p[i], p[j])
    35  }
    36  
    37  // CompareFunc implements Comparer.
    38  func (p Float64Slice) CompareFunc(x interface{}) func(int) int {
    39  	e := x.(float64)
    40  	return func(i int) int {
    41  		return cmpFloat64(p[i], e)
    42  	}
    43  }
    44  
    45  // RadixRange implements RadixInterface.
    46  func (p Float64Slice) RadixRange() (int, int) {
    47  	return 0, 63
    48  }
    49  
    50  // RadixFunc implements RadixInterface.
    51  func (p Float64Slice) RadixFunc(r int) RadixTest {
    52  	if r == 0 {
    53  		return func(i int) bool {
    54  			return p[i] >= 0
    55  		}
    56  	}
    57  
    58  	mask := uint64(1) << uint(63-r)
    59  	sign := uint64(1) << 63
    60  	return func(i int) bool {
    61  		bits := math.Float64bits(p[i])
    62  		return (bits&mask != 0) != (bits&sign != 0)
    63  	}
    64  }
    65  
    66  // Sort is a convenience method.
    67  func (p Float64Slice) Sort() { radix(p) }
    68  
    69  // Radix is a convenience method.
    70  func (p Float64Slice) Radix() { radix(p) }
    71  
    72  // Search is a convenience method.
    73  func (p Float64Slice) Search(x float64) int { return SearchFloat64s(p, x) }
    74  
    75  // SearchFor is a convenience method.
    76  func (p Float64Slice) SearchFor(x interface{}) int { return SearchFloat64s(p, x.(float64)) }
    77  
    78  // Float64s sorts a slice of float64s in increasing order.
    79  func Float64s(a []float64) { radix(Float64Slice(a)) }
    80  
    81  // SearchFloat64s searches for x in a sorted slice of float64s and returns the index as specified by sort.Search.
    82  // The return value is the index to insert x if x is not present (it could be len(a)).
    83  // The slice must be sorted in ascending order.
    84  func SearchFloat64s(a []float64, x float64) int {
    85  	return sort.Search(len(a), func(i int) bool { return a[i] >= x })
    86  }
    87  
    88  // Float64sAreSorted tests whether a slice of float64s is sorted in increasing order.
    89  func Float64sAreSorted(a []float64) bool { return sort.IsSorted(Float64Slice(a)) }
    90  
    91  // Float32Slice attaches the methods of sort.Interface to []float32, sorting in increasing order.
    92  type Float32Slice []float32
    93  
    94  // Len implements sort.Interface.
    95  func (p Float32Slice) Len() int { return len(p) }
    96  
    97  // Less implements sort.Interface.
    98  func (p Float32Slice) Less(i, j int) bool { return p[i] < p[j] || isNaN32(p[i]) && !isNaN32(p[j]) }
    99  
   100  // Swap implements sort.Interface.
   101  func (p Float32Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
   102  
   103  func cmpFloat32(x, y float32) int {
   104  	if x == y {
   105  		return 0
   106  	}
   107  
   108  	if x < y {
   109  		return -1
   110  	}
   111  
   112  	return +1
   113  }
   114  
   115  // Compare implements Comparer.
   116  func (p Float32Slice) Compare(i, j int) int {
   117  	return cmpFloat32(p[i], p[j])
   118  }
   119  
   120  // CompareFunc implements Comparer.
   121  func (p Float32Slice) CompareFunc(x interface{}) func(int) int {
   122  	e := x.(float32)
   123  	return func(i int) int {
   124  		return cmpFloat32(p[i], e)
   125  	}
   126  }
   127  
   128  // RadixRange implements RadixInterface.
   129  func (p Float32Slice) RadixRange() (int, int) {
   130  	return 0, 31
   131  }
   132  
   133  // RadixFunc implements RadixInterface.
   134  func (p Float32Slice) RadixFunc(r int) RadixTest {
   135  	if r == 0 {
   136  		return func(i int) bool {
   137  			return p[i] >= 0
   138  		}
   139  	}
   140  
   141  	mask := uint32(1) << uint(31-r)
   142  	sign := uint32(1) << 31
   143  	return func(i int) bool {
   144  		bits := math.Float32bits(p[i])
   145  		return (bits&mask != 0) != (bits&sign != 0)
   146  	}
   147  }
   148  
   149  // Sort is a convenience method.
   150  func (p Float32Slice) Sort() { radix(p) }
   151  
   152  // Radix is a convenience method.
   153  func (p Float32Slice) Radix() { radix(p) }
   154  
   155  // Search is a convenience method.
   156  func (p Float32Slice) Search(x float32) int { return SearchFloat32s(p, x) }
   157  
   158  // SearchFor is a convenience method.
   159  func (p Float32Slice) SearchFor(x interface{}) int { return SearchFloat32s(p, x.(float32)) }
   160  
   161  // Float32s sorts a slice of float32s in increasing order.
   162  func Float32s(a []float32) { radix(Float32Slice(a)) }
   163  
   164  // SearchFloat32s searches for x in a sorted slice of float32s and returns the index as specified by sort.Search.
   165  // The return value is the index to insert x if x is not present (it could be len(a)).
   166  // The slice must be sorted in ascending order.
   167  func SearchFloat32s(a []float32, x float32) int {
   168  	return sort.Search(len(a), func(i int) bool { return a[i] >= x })
   169  }
   170  
   171  // Float32sAreSorted tests whether a slice of float32s is sorted in increasing order.
   172  func Float32sAreSorted(a []float32) bool { return sort.IsSorted(Float32Slice(a)) }