github.com/prysmaticlabs/prysm@v1.4.4/shared/mathutil/math_helper_test.go (about) 1 package mathutil_test 2 3 import ( 4 "math" 5 "testing" 6 7 "github.com/prysmaticlabs/prysm/shared/mathutil" 8 "github.com/prysmaticlabs/prysm/shared/testutil/require" 9 ) 10 11 func TestIntegerSquareRoot(t *testing.T) { 12 tt := []struct { 13 number uint64 14 root uint64 15 }{ 16 { 17 number: 20, 18 root: 4, 19 }, 20 { 21 number: 200, 22 root: 14, 23 }, 24 { 25 number: 1987, 26 root: 44, 27 }, 28 { 29 number: 34989843, 30 root: 5915, 31 }, 32 { 33 number: 97282, 34 root: 311, 35 }, 36 { 37 number: 1 << 32, 38 root: 1 << 16, 39 }, 40 { 41 number: (1 << 32) + 1, 42 root: 1 << 16, 43 }, 44 { 45 number: 1 << 33, 46 root: 92681, 47 }, 48 { 49 number: 1 << 60, 50 root: 1 << 30, 51 }, 52 { 53 number: 1 << 53, 54 root: 94906265, 55 }, 56 { 57 number: 1 << 62, 58 root: 1 << 31, 59 }, 60 { 61 number: 1024, 62 root: 32, 63 }, 64 { 65 number: 4, 66 root: 2, 67 }, 68 { 69 number: 16, 70 root: 4, 71 }, 72 { 73 number: 5508423000000000, 74 root: 74218750, 75 }, 76 { 77 number: 4503599761588224, 78 root: 67108864, 79 }, 80 } 81 82 for _, testVals := range tt { 83 require.Equal(t, testVals.root, mathutil.IntegerSquareRoot(testVals.number)) 84 } 85 } 86 87 func BenchmarkIntegerSquareRootBelow52Bits(b *testing.B) { 88 val := uint64(1 << 33) 89 for i := 0; i < b.N; i++ { 90 require.Equal(b, uint64(92681), mathutil.IntegerSquareRoot(val)) 91 } 92 } 93 94 func BenchmarkIntegerSquareRootAbove52Bits(b *testing.B) { 95 val := uint64(1 << 62) 96 for i := 0; i < b.N; i++ { 97 require.Equal(b, uint64(1<<31), mathutil.IntegerSquareRoot(val)) 98 } 99 } 100 101 func BenchmarkIntegerSquareRoot_WithDatatable(b *testing.B) { 102 val := uint64(1024) 103 for i := 0; i < b.N; i++ { 104 require.Equal(b, uint64(32), mathutil.IntegerSquareRoot(val)) 105 } 106 } 107 108 func TestCeilDiv8(t *testing.T) { 109 tests := []struct { 110 number int 111 div8 int 112 }{ 113 { 114 number: 20, 115 div8: 3, 116 }, 117 { 118 number: 200, 119 div8: 25, 120 }, 121 { 122 number: 1987, 123 div8: 249, 124 }, 125 { 126 number: 1, 127 div8: 1, 128 }, 129 { 130 number: 97282, 131 div8: 12161, 132 }, 133 } 134 135 for _, tt := range tests { 136 require.Equal(t, tt.div8, mathutil.CeilDiv8(tt.number)) 137 } 138 } 139 140 func TestIsPowerOf2(t *testing.T) { 141 tests := []struct { 142 a uint64 143 b bool 144 }{ 145 { 146 a: 2, 147 b: true, 148 }, 149 { 150 a: 64, 151 b: true, 152 }, 153 { 154 a: 100, 155 b: false, 156 }, 157 { 158 a: 1024, 159 b: true, 160 }, 161 { 162 a: 0, 163 b: false, 164 }, 165 } 166 for _, tt := range tests { 167 require.Equal(t, tt.b, mathutil.IsPowerOf2(tt.a)) 168 } 169 } 170 171 func TestPowerOf2(t *testing.T) { 172 tests := []struct { 173 a uint64 174 b uint64 175 }{ 176 { 177 a: 3, 178 b: 8, 179 }, 180 { 181 a: 20, 182 b: 1048576, 183 }, 184 { 185 a: 11, 186 b: 2048, 187 }, 188 { 189 a: 8, 190 b: 256, 191 }, 192 } 193 for _, tt := range tests { 194 require.Equal(t, tt.b, mathutil.PowerOf2(tt.a)) 195 } 196 } 197 198 func TestMaxValue(t *testing.T) { 199 tests := []struct { 200 a uint64 201 b uint64 202 result uint64 203 }{ 204 { 205 a: 10, 206 b: 8, 207 result: 10, 208 }, 209 { 210 a: 300, 211 b: 256, 212 result: 300, 213 }, 214 { 215 a: 1200, 216 b: 1024, 217 result: 1200, 218 }, 219 { 220 a: 4500, 221 b: 4096, 222 result: 4500, 223 }, 224 { 225 a: 9999, 226 b: 9999, 227 result: 9999, 228 }, 229 } 230 for _, tt := range tests { 231 require.Equal(t, tt.result, mathutil.Max(tt.a, tt.b)) 232 } 233 } 234 235 func TestMinValue(t *testing.T) { 236 tests := []struct { 237 a uint64 238 b uint64 239 result uint64 240 }{ 241 { 242 a: 10, 243 b: 8, 244 result: 8, 245 }, 246 { 247 a: 300, 248 b: 256, 249 result: 256, 250 }, 251 { 252 a: 1200, 253 b: 1024, 254 result: 1024, 255 }, 256 { 257 a: 4500, 258 b: 4096, 259 result: 4096, 260 }, 261 { 262 a: 9999, 263 b: 9999, 264 result: 9999, 265 }, 266 } 267 for _, tt := range tests { 268 require.Equal(t, tt.result, mathutil.Min(tt.a, tt.b)) 269 } 270 } 271 272 func TestMul64(t *testing.T) { 273 type args struct { 274 a uint64 275 b uint64 276 } 277 tests := []struct { 278 args args 279 res uint64 280 err bool 281 }{ 282 {args: args{0, 1}, res: 0, err: false}, 283 {args: args{1 << 32, 1}, res: 1 << 32, err: false}, 284 {args: args{1 << 32, 100}, res: 429496729600, err: false}, 285 {args: args{1 << 32, 1 << 31}, res: 9223372036854775808, err: false}, 286 {args: args{1 << 32, 1 << 32}, res: 0, err: true}, 287 {args: args{1 << 62, 2}, res: 9223372036854775808, err: false}, 288 {args: args{1 << 62, 4}, res: 0, err: true}, 289 {args: args{1 << 63, 1}, res: 9223372036854775808, err: false}, 290 {args: args{1 << 63, 2}, res: 0, err: true}, 291 } 292 for _, tt := range tests { 293 got, err := mathutil.Mul64(tt.args.a, tt.args.b) 294 if tt.err && err == nil { 295 t.Errorf("Mul64() Expected Error = %v, want error", tt.err) 296 continue 297 } 298 if tt.res != got { 299 t.Errorf("Mul64() %v, want %v", got, tt.res) 300 } 301 } 302 } 303 304 func TestAdd64(t *testing.T) { 305 type args struct { 306 a uint64 307 b uint64 308 } 309 tests := []struct { 310 args args 311 res uint64 312 err bool 313 }{ 314 {args: args{0, 1}, res: 1, err: false}, 315 {args: args{1 << 32, 1}, res: 4294967297, err: false}, 316 {args: args{1 << 32, 100}, res: 4294967396, err: false}, 317 {args: args{1 << 31, 1 << 31}, res: 4294967296, err: false}, 318 {args: args{1 << 63, 1 << 63}, res: 0, err: true}, 319 {args: args{1 << 63, 1}, res: 9223372036854775809, err: false}, 320 {args: args{math.MaxUint64, 1}, res: 0, err: true}, 321 {args: args{math.MaxUint64, 0}, res: math.MaxUint64, err: false}, 322 {args: args{1 << 63, 2}, res: 9223372036854775810, err: false}, 323 } 324 for _, tt := range tests { 325 got, err := mathutil.Add64(tt.args.a, tt.args.b) 326 if tt.err && err == nil { 327 t.Errorf("Add64() Expected Error = %v, want error", tt.err) 328 continue 329 } 330 if tt.res != got { 331 t.Errorf("Add64() %v, want %v", got, tt.res) 332 } 333 } 334 }