go.mway.dev/math@v0.3.4-0.20220903004814-3c8fcf9df0ca/math_test.go (about) 1 // Copyright (c) 2022 Matt Way 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to 5 // deal in the Software without restriction, including without limitation the 6 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 // sell copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 // IN THE THE SOFTWARE. 20 21 package math_test 22 23 import ( 24 "testing" 25 "time" 26 27 "github.com/stretchr/testify/require" 28 "go.mway.dev/math" 29 ) 30 31 func TestAbs(t *testing.T) { 32 require.Equal(t, 10, math.Abs(10)) 33 require.Equal(t, int(10), math.Abs(-10)) 34 require.Equal(t, int8(10), math.Abs[int8](10)) 35 require.Equal(t, int8(10), math.Abs[int8](-10)) 36 require.Equal(t, int16(10), math.Abs[int16](10)) 37 require.Equal(t, int16(10), math.Abs[int16](-10)) 38 require.Equal(t, int32(10), math.Abs[int32](10)) 39 require.Equal(t, int32(10), math.Abs[int32](-10)) 40 require.Equal(t, int64(10), math.Abs[int64](10)) 41 require.Equal(t, int64(10), math.Abs[int64](-10)) 42 require.Equal(t, time.Duration(10), math.Abs[time.Duration](-10)) 43 require.Equal(t, float32(10.0), math.Abs[float32](10.0)) 44 require.Equal(t, float32(10.0), math.Abs[float32](-10.0)) 45 require.Equal(t, float64(10.0), math.Abs(-10.0)) 46 require.Equal(t, float64(10.0), math.Abs(10.0)) 47 } 48 49 func TestMin(t *testing.T) { 50 require.Equal(t, 10, math.Min(100, 10)) 51 require.Equal(t, 10, math.Min(10, 100)) 52 require.Equal(t, int8(10), math.Min[int8](100, 10)) 53 require.Equal(t, int8(10), math.Min[int8](10, 100)) 54 require.Equal(t, int16(10), math.Min[int16](100, 10)) 55 require.Equal(t, int16(10), math.Min[int16](10, 100)) 56 require.Equal(t, int32(10), math.Min[int32](100, 10)) 57 require.Equal(t, int32(10), math.Min[int32](10, 100)) 58 require.Equal(t, int64(10), math.Min[int64](100, 10)) 59 require.Equal(t, int64(10), math.Min[int64](10, 100)) 60 require.Equal(t, uint(10), math.Min[uint](100, 10)) 61 require.Equal(t, uint(10), math.Min[uint](10, 100)) 62 require.Equal(t, uint8(10), math.Min[uint8](100, 10)) 63 require.Equal(t, uint8(10), math.Min[uint8](10, 10)) 64 require.Equal(t, uint16(10), math.Min[uint16](100, 10)) 65 require.Equal(t, uint16(10), math.Min[uint16](10, 100)) 66 require.Equal(t, uint32(10), math.Min[uint32](100, 10)) 67 require.Equal(t, uint32(10), math.Min[uint32](10, 100)) 68 require.Equal(t, uint64(10), math.Min[uint64](100, 10)) 69 require.Equal(t, uint64(10), math.Min[uint64](10, 100)) 70 require.Equal(t, time.Duration(10), math.Min[time.Duration](10, 100)) 71 require.Equal(t, float32(10.0), math.Min[float32](10.0, 100.0)) 72 require.Equal(t, float32(10.0), math.Min[float32](100.0, 10.0)) 73 require.Equal(t, float64(10.0), math.Min(10.0, 100.0)) 74 require.Equal(t, float64(10.0), math.Min(100.0, 10.0)) 75 } 76 77 func TestMinN(t *testing.T) { 78 require.Equal(t, 0, math.MinN[int]()) 79 require.Equal(t, 10, math.MinN(10)) 80 require.Equal(t, 10, math.MinN(100, 50, 10)) 81 require.Equal(t, 10, math.MinN(10, 50, 100)) 82 require.Equal(t, int8(10), math.MinN[int8](100, 50, 10)) 83 require.Equal(t, int8(10), math.MinN[int8](100, 50, 10, 50)) 84 require.Equal(t, int8(10), math.MinN[int8](100, 50, 10, 50, 100)) 85 require.Equal(t, int8(10), math.MinN[int8](100, 80, 60, 10)) 86 require.Equal(t, int8(10), math.MinN[int8](100, 80, 60, 40, 20, 10)) 87 require.Equal(t, int8(10), math.MinN[int8](10, 50, 100)) 88 require.Equal(t, int16(10), math.MinN[int16](100, 50, 10)) 89 require.Equal(t, int16(10), math.MinN[int16](10, 50, 100)) 90 require.Equal(t, int32(10), math.MinN[int32](100, 50, 10)) 91 require.Equal(t, int32(10), math.MinN[int32](10, 50, 100)) 92 require.Equal(t, int64(10), math.MinN[int64](100, 50, 10)) 93 require.Equal(t, int64(10), math.MinN[int64](10, 50, 100)) 94 require.Equal(t, uint(10), math.MinN[uint](100, 50, 10)) 95 require.Equal(t, uint(10), math.MinN[uint](10, 50, 100)) 96 require.Equal(t, uint8(10), math.MinN[uint8](100, 50, 10)) 97 require.Equal(t, uint8(10), math.MinN[uint8](10, 10)) 98 require.Equal(t, uint16(10), math.MinN[uint16](100, 50, 10)) 99 require.Equal(t, uint16(10), math.MinN[uint16](10, 50, 100)) 100 require.Equal(t, uint32(10), math.MinN[uint32](100, 50, 10)) 101 require.Equal(t, uint32(10), math.MinN[uint32](10, 50, 100)) 102 require.Equal(t, uint64(10), math.MinN[uint64](100, 50, 10)) 103 require.Equal(t, uint64(10), math.MinN[uint64](10, 50, 100)) 104 require.Equal(t, time.Duration(10), math.MinN[time.Duration](10, 50, 100)) 105 require.Equal(t, float32(10.0), math.MinN[float32](10.0, 50.0, 100.0)) 106 require.Equal(t, float32(10.0), math.MinN[float32](100.0, 50.0, 10.0)) 107 require.Equal(t, float64(10.0), math.MinN(10.0, 50.0, 100.0)) 108 require.Equal(t, float64(10.0), math.MinN(100.0, 50.0, 10.0)) 109 } 110 111 func TestMax(t *testing.T) { 112 require.Equal(t, 100, math.Max(10, 100)) 113 require.Equal(t, 100, math.Max(100, 100)) 114 require.Equal(t, int8(100), math.Max[int8](10, 100)) 115 require.Equal(t, int8(100), math.Max[int8](100, 10)) 116 require.Equal(t, int16(100), math.Max[int16](10, 100)) 117 require.Equal(t, int16(100), math.Max[int16](100, 10)) 118 require.Equal(t, int32(100), math.Max[int32](10, 100)) 119 require.Equal(t, int32(100), math.Max[int32](100, 10)) 120 require.Equal(t, int64(100), math.Max[int64](10, 100)) 121 require.Equal(t, int64(100), math.Max[int64](100, 10)) 122 require.Equal(t, uint(100), math.Max[uint](10, 100)) 123 require.Equal(t, uint(100), math.Max[uint](100, 10)) 124 require.Equal(t, uint8(100), math.Max[uint8](10, 100)) 125 require.Equal(t, uint8(100), math.Max[uint8](100, 10)) 126 require.Equal(t, uint16(100), math.Max[uint16](10, 100)) 127 require.Equal(t, uint16(100), math.Max[uint16](100, 10)) 128 require.Equal(t, uint32(100), math.Max[uint32](10, 100)) 129 require.Equal(t, uint32(100), math.Max[uint32](100, 10)) 130 require.Equal(t, uint64(100), math.Max[uint64](10, 100)) 131 require.Equal(t, uint64(100), math.Max[uint64](100, 10)) 132 require.Equal(t, time.Duration(100), math.Max[time.Duration](100, 10)) 133 require.Equal(t, float32(100.0), math.Max[float32](10.0, 100.0)) 134 require.Equal(t, float32(100.0), math.Max[float32](100.0, 10.0)) 135 require.Equal(t, float64(100.0), math.Max(10.0, 100.0)) 136 require.Equal(t, float64(100.0), math.Max(100.0, 10.0)) 137 } 138 139 func TestMaxN(t *testing.T) { 140 require.Equal(t, 0, math.MaxN[int]()) 141 require.Equal(t, 10, math.MaxN(10)) 142 require.Equal(t, 100, math.MaxN(10, 50, 100)) 143 require.Equal(t, 100, math.MaxN(100, 50, 100)) 144 require.Equal(t, int8(100), math.MaxN[int8](10, 50, 100)) 145 require.Equal(t, int8(100), math.MaxN[int8](10, 50, 100, 50)) 146 require.Equal(t, int8(100), math.MaxN[int8](10, 50, 50, 100)) 147 require.Equal(t, int8(100), math.MaxN[int8](10, 50, 50, 0, 100)) 148 require.Equal(t, int8(100), math.MaxN[int8](100, 50, 10)) 149 require.Equal(t, int16(100), math.MaxN[int16](10, 50, 100)) 150 require.Equal(t, int16(100), math.MaxN[int16](100, 50, 10)) 151 require.Equal(t, int32(100), math.MaxN[int32](10, 50, 100)) 152 require.Equal(t, int32(100), math.MaxN[int32](100, 50, 10)) 153 require.Equal(t, int64(100), math.MaxN[int64](10, 50, 100)) 154 require.Equal(t, int64(100), math.MaxN[int64](100, 50, 10)) 155 require.Equal(t, uint(100), math.MaxN[uint](10, 50, 100)) 156 require.Equal(t, uint(100), math.MaxN[uint](100, 50, 10)) 157 require.Equal(t, uint8(100), math.MaxN[uint8](10, 50, 100)) 158 require.Equal(t, uint8(100), math.MaxN[uint8](100, 50, 10)) 159 require.Equal(t, uint16(100), math.MaxN[uint16](10, 50, 100)) 160 require.Equal(t, uint16(100), math.MaxN[uint16](100, 50, 10)) 161 require.Equal(t, uint32(100), math.MaxN[uint32](10, 50, 100)) 162 require.Equal(t, uint32(100), math.MaxN[uint32](100, 50, 10)) 163 require.Equal(t, uint64(100), math.MaxN[uint64](10, 50, 100)) 164 require.Equal(t, uint64(100), math.MaxN[uint64](100, 50, 10)) 165 require.Equal(t, time.Duration(100), math.MaxN[time.Duration](100, 50, 10)) 166 require.Equal(t, float32(100.0), math.MaxN[float32](10.0, 50.0, 100.0)) 167 require.Equal(t, float32(100.0), math.MaxN[float32](100.0, 50.0, 10.0)) 168 require.Equal(t, float64(100.0), math.MaxN(10.0, 50.0, 100.0)) 169 require.Equal(t, float64(100.0), math.MaxN(100.0, 50.0, 10.0)) 170 } 171 172 func TestMean(t *testing.T) { 173 require.Equal(t, 3, math.Mean(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 174 require.Equal(t, int8(3), math.Mean[int8](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 175 require.Equal(t, int16(3), math.Mean[int16](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 176 require.Equal(t, int32(3), math.Mean[int32](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 177 require.Equal(t, int64(3), math.Mean[int64](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 178 require.Equal(t, uint(3), math.Mean[uint](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 179 require.Equal(t, uint8(3), math.Mean[uint8](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 180 require.Equal(t, uint16(3), math.Mean[uint16](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 181 require.Equal(t, uint32(3), math.Mean[uint32](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 182 require.Equal(t, uint64(3), math.Mean[uint64](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 183 require.Equal(t, time.Duration(3), math.Mean[time.Duration](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 184 require.Equal(t, float32(3.5), math.Mean[float32](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 185 require.Equal(t, float32(3.5), math.Mean[float32](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 186 require.Equal(t, float64(3.5), math.Mean[float64](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 187 require.Equal(t, float64(3.5), math.Mean[float64](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 188 } 189 190 func TestMeanFloat64(t *testing.T) { 191 require.Equal(t, 3.5, math.MeanFloat64(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 192 require.Equal(t, 3.5, math.MeanFloat64[int8](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 193 require.Equal(t, 3.5, math.MeanFloat64[int16](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 194 require.Equal(t, 3.5, math.MeanFloat64[int32](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 195 require.Equal(t, 3.5, math.MeanFloat64[int64](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 196 require.Equal(t, 3.5, math.MeanFloat64[uint](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 197 require.Equal(t, 3.5, math.MeanFloat64[uint8](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 198 require.Equal(t, 3.5, math.MeanFloat64[uint16](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 199 require.Equal(t, 3.5, math.MeanFloat64[uint32](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 200 require.Equal(t, 3.5, math.MeanFloat64[uint64](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 201 require.Equal(t, 3.5, math.MeanFloat64[time.Duration](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 202 require.Equal(t, float64(3.5), math.MeanFloat64[float32](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 203 require.Equal(t, float64(3.5), math.MeanFloat64[float32](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 204 require.Equal(t, float64(3.5), math.MeanFloat64[float64](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 205 require.Equal(t, float64(3.5), math.MeanFloat64[float64](1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6)) 206 } 207 208 func TestClamp(t *testing.T) { 209 require.Equal(t, 5, math.Clamp(5, 1, 10)) 210 require.Equal(t, 10, math.Clamp(15, 1, 10)) 211 require.Equal(t, 1, math.Clamp(-1, 1, 10)) 212 require.Equal(t, 1.5, math.Clamp(1.5, 1.0, 2.0)) 213 require.Equal(t, time.Second, math.Clamp(time.Hour, time.Millisecond, time.Second)) 214 } 215 216 func TestClampMin(t *testing.T) { 217 require.Equal(t, 5, math.ClampMin(5, 1)) 218 require.Equal(t, 5, math.ClampMin(1, 5)) 219 require.Equal(t, 1, math.ClampMin(-1, 1)) 220 require.Equal(t, 1.0, math.ClampMin(0.5, 1.0)) 221 require.Equal(t, time.Second, math.ClampMin(time.Second, time.Millisecond)) 222 } 223 224 func TestClampMax(t *testing.T) { 225 require.Equal(t, 1, math.ClampMax(5, 1)) 226 require.Equal(t, 1, math.ClampMax(1, 5)) 227 require.Equal(t, -1, math.ClampMax(-1, 1)) 228 require.Equal(t, 1.0, math.ClampMax(1.5, 1.0)) 229 require.Equal(t, time.Millisecond, math.ClampMax(time.Second, time.Millisecond)) 230 } 231 232 func TestNextPowerOf2(t *testing.T) { 233 cases := [][2]int{ 234 // give, want 235 {0, 1}, 236 {1, 1}, 237 {2, 2}, 238 {3, 4}, 239 {4, 4}, 240 {5, 8}, 241 {6, 8}, 242 {7, 8}, 243 {8, 8}, 244 {9, 16}, 245 {10, 16}, 246 {11, 16}, 247 {12, 16}, 248 {13, 16}, 249 {14, 16}, 250 {15, 16}, 251 {16, 16}, 252 {17, 32}, 253 {18, 32}, 254 {19, 32}, 255 {20, 32}, 256 {21, 32}, 257 {22, 32}, 258 {23, 32}, 259 {24, 32}, 260 {25, 32}, 261 {26, 32}, 262 {27, 32}, 263 {28, 32}, 264 {29, 32}, 265 {30, 32}, 266 {31, 32}, 267 {32, 32}, 268 } 269 270 for _, pair := range cases { 271 require.Equal(t, pair[1], math.NextPowerOf2(pair[0])) 272 require.Equal(t, int8(pair[1]), math.NextPowerOf2(int8(pair[0]))) 273 require.Equal(t, int16(pair[1]), math.NextPowerOf2(int16(pair[0]))) 274 require.Equal(t, int32(pair[1]), math.NextPowerOf2(int32(pair[0]))) 275 require.Equal(t, int64(pair[1]), math.NextPowerOf2(int64(pair[0]))) 276 require.Equal(t, uint(pair[1]), math.NextPowerOf2(uint(pair[0]))) 277 require.Equal(t, uint8(pair[1]), math.NextPowerOf2(uint8(pair[0]))) 278 require.Equal(t, uint16(pair[1]), math.NextPowerOf2(uint16(pair[0]))) 279 require.Equal(t, uint32(pair[1]), math.NextPowerOf2(uint32(pair[0]))) 280 require.Equal(t, uint64(pair[1]), math.NextPowerOf2(uint64(pair[0]))) 281 require.Equal(t, float32(pair[1]), math.NextPowerOf2(float32(pair[0]))) 282 require.Equal(t, float64(pair[1]), math.NextPowerOf2(float64(pair[0]))) 283 require.Equal(t, time.Duration(pair[1]), math.NextPowerOf2(time.Duration(pair[0]))) 284 } 285 } 286 287 func TestClosestPowerOf2(t *testing.T) { 288 cases := [][2]int{ 289 // give, want 290 {0, 1}, 291 {1, 1}, 292 {2, 2}, 293 {3, 4}, 294 {4, 4}, 295 {5, 4}, 296 {6, 8}, 297 {7, 8}, 298 {8, 8}, 299 {9, 8}, 300 {10, 8}, 301 {11, 8}, 302 {12, 16}, 303 {13, 16}, 304 {14, 16}, 305 {15, 16}, 306 {16, 16}, 307 {17, 16}, 308 {18, 16}, 309 {19, 16}, 310 {20, 16}, 311 {21, 16}, 312 {22, 16}, 313 {23, 16}, 314 {24, 32}, 315 {25, 32}, 316 {26, 32}, 317 {27, 32}, 318 {28, 32}, 319 {29, 32}, 320 {30, 32}, 321 {31, 32}, 322 {32, 32}, 323 } 324 325 for _, pair := range cases { 326 require.Equal(t, pair[1], math.ClosestPowerOf2(pair[0])) 327 require.Equal(t, int8(pair[1]), math.ClosestPowerOf2(int8(pair[0]))) 328 require.Equal(t, int16(pair[1]), math.ClosestPowerOf2(int16(pair[0]))) 329 require.Equal(t, int32(pair[1]), math.ClosestPowerOf2(int32(pair[0]))) 330 require.Equal(t, int64(pair[1]), math.ClosestPowerOf2(int64(pair[0]))) 331 require.Equal(t, uint(pair[1]), math.ClosestPowerOf2(uint(pair[0]))) 332 require.Equal(t, uint8(pair[1]), math.ClosestPowerOf2(uint8(pair[0]))) 333 require.Equal(t, uint16(pair[1]), math.ClosestPowerOf2(uint16(pair[0]))) 334 require.Equal(t, uint32(pair[1]), math.ClosestPowerOf2(uint32(pair[0]))) 335 require.Equal(t, uint64(pair[1]), math.ClosestPowerOf2(uint64(pair[0]))) 336 require.Equal(t, float32(pair[1]), math.ClosestPowerOf2(float32(pair[0]))) 337 require.Equal(t, float64(pair[1]), math.ClosestPowerOf2(float64(pair[0]))) 338 require.Equal(t, time.Duration(pair[1]), math.ClosestPowerOf2(time.Duration(pair[0]))) 339 } 340 } 341 342 func TestPrecision(t *testing.T) { 343 require.Equal(t, 1.2345, math.Precision(1.2345, -1)) 344 require.Equal(t, 1.0, math.Precision(1.2345, 0)) 345 require.Equal(t, 1.2, math.Precision(1.2345, 1)) 346 require.Equal(t, 1.23, math.Precision(1.2345, 2)) 347 require.Equal(t, 1.235, math.Precision(1.2345, 3)) 348 require.Equal(t, 1.2345, math.Precision(1.2345, 4)) 349 } 350 351 func TestFastrand(t *testing.T) { 352 var ( 353 reported = make(map[int64]struct{}) 354 wantLen = 1024 355 ) 356 357 for i := 0; i < wantLen; i++ { 358 reported[math.Fastrand[int64]()] = struct{}{} 359 } 360 361 require.Len(t, reported, wantLen) 362 } 363 364 func TestFastrandn(t *testing.T) { 365 var ( 366 reported = make(map[int]struct{}) 367 bound = 1<<24 - 1 368 wantLen = 1024 369 ) 370 371 for i := 0; i < wantLen; i++ { 372 n := math.Fastrandn(bound) 373 require.True(t, n < bound) 374 reported[n] = struct{}{} 375 } 376 377 require.InDelta(t, wantLen, len(reported), float64(wantLen)/float64(100)) 378 }