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)) }