github.com/jgbaldwinbrown/perf@v0.1.1/benchunit/scale_test.go (about) 1 // Copyright 2022 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package benchunit 6 7 import ( 8 "math" 9 "testing" 10 ) 11 12 func TestScale(t *testing.T) { 13 var cls Class 14 test := func(num float64, want, wantPred string) { 15 t.Helper() 16 17 got := Scale(num, cls) 18 if got != want { 19 t.Errorf("for %v, got %s, want %s", num, got, want) 20 } 21 22 // Check what happens when this number is exactly on 23 // the crux between two scale factors. 24 pred := math.Nextafter(num, 0) 25 got = Scale(pred, cls) 26 if got != wantPred { 27 dir := "-ε" 28 if num < 0 { 29 dir = "+ε" 30 } 31 t.Errorf("for %v%s, got %s, want %s", num, dir, got, wantPred) 32 } 33 } 34 35 cls = Decimal 36 // Smoke tests 37 test(0, "0.000", "0.000") 38 test(1, "1.000", "1.000") 39 test(-1, "-1.000", "-1.000") 40 // Full range 41 test(9999500000000000, "9999.5T", "9999.5T") 42 test(999950000000000, "1000.0T", "999.9T") 43 test(99995000000000, "100.0T", "99.99T") 44 test(9999500000000, "10.00T", "9.999T") 45 test(999950000000, "1.000T", "999.9G") 46 test(99995000000, "100.0G", "99.99G") 47 test(9999500000, "10.00G", "9.999G") 48 test(999950000, "1.000G", "999.9M") 49 test(99995000, "100.0M", "99.99M") 50 test(9999500, "10.00M", "9.999M") 51 test(999950, "1.000M", "999.9k") 52 test(99995, "100.0k", "99.99k") 53 test(9999.5, "10.00k", "9.999k") 54 test(999.95, "1.000k", "999.9") 55 test(99.995, "100.0", "99.99") 56 test(9.9995, "10.00", "9.999") 57 test(.99995, "1.000", "999.9m") 58 test(.099995, "100.0m", "99.99m") 59 test(.0099995, "10.00m", "9.999m") 60 test(.00099995, "1.000m", "999.9µ") 61 test(.000099995, "100.0µ", "99.99µ") 62 test(.0000099995, "10.00µ", "9.999µ") 63 test(.00000099995, "1.000µ", "999.9n") 64 test(.000000099995, "100.0n", "99.99n") 65 test(.0000000099995, "10.00n", "9.999n") 66 test(.00000000099995, "1.000n", "0.9999n") // First pred we won't up-scale 67 68 // Below the smallest scale unit rounding gets imperfect, but 69 // it's off from the ideal by at most one ulp, so we accept it. 70 test(math.Nextafter(.000000000099995, 1), "0.1000n", "0.09999n") 71 test(.0000000000099995, "0.01000n", "0.009999n") 72 test(math.Nextafter(.00000000000099995, 1), "0.001000n", "0.0009999n") 73 test(.000000000000099995, "0.0001000n", "0.00009999n") 74 test(.0000000000000099995, "0.00001000n", "0.000009999n") 75 test(math.Nextafter(.00000000000000099995, 1), "0.000001000n", "0.0000009999n") 76 77 // Misc 78 test(-99995000000000, "-100.0T", "-99.99T") 79 test(-.0000000099995, "-10.00n", "-9.999n") 80 81 cls = Binary 82 // Smoke tests 83 test(0, "0.000", "0.000") 84 test(1, "1.000", "1.000") 85 test(-1, "-1.000", "-1.000") 86 // Full range 87 test(.99995*(1<<50), "1023.9Ti", "1023.9Ti") 88 test(99.995*(1<<40), "100.0Ti", "99.99Ti") 89 test(9.9995*(1<<40), "10.00Ti", "9.999Ti") 90 test(.99995*(1<<40), "1.000Ti", "1023.9Gi") 91 test(99.995*(1<<30), "100.0Gi", "99.99Gi") 92 test(9.9995*(1<<30), "10.00Gi", "9.999Gi") 93 test(.99995*(1<<30), "1.000Gi", "1023.9Mi") 94 test(99.995*(1<<20), "100.0Mi", "99.99Mi") 95 test(9.9995*(1<<20), "10.00Mi", "9.999Mi") 96 test(.99995*(1<<20), "1.000Mi", "1023.9Ki") 97 test(99.995*(1<<10), "100.0Ki", "99.99Ki") 98 test(9.9995*(1<<10), "10.00Ki", "9.999Ki") 99 test(.99995*(1<<10), "1.000Ki", "1023.9") 100 test(99.995*(1<<0), "100.0", "99.99") 101 test(9.9995*(1<<0), "10.00", "9.999") 102 test(.99995, "1.000", "0.9999") 103 test(.099995, "0.1000", "0.09999") 104 test(.0099995, "0.01000", "0.009999") 105 test(.00099995, "0.001000", "0.0009999") 106 test(.000099995, "0.0001000", "0.00009999") 107 test(.0000099995, "0.00001000", "0.000009999") 108 test(.00000099995, "0.000001000", "0.0000009999") 109 // We stop at 10 digits after the decimal. Again, rounding 110 // gets a little weird. 111 test(.00000009995, "0.0000001000", "0.0000000999") 112 test(math.Nextafter(.00000000995, 1), "0.0000000100", "0.0000000099") 113 test(.00000000095, "0.0000000010", "0.0000000009") 114 test(.00000000005, "0.0000000001", "0.0000000000") 115 test(.000000000009, "0.0000000000", "0.0000000000") 116 } 117 118 func TestNoOpScaler(t *testing.T) { 119 test := func(val float64, want string) { 120 t.Helper() 121 got := NoOpScaler.Format(val) 122 if got != want { 123 t.Errorf("for %v, got %s, want %s", val, got, want) 124 } 125 } 126 127 test(1, "1") 128 test(123456789, "123456789") 129 test(123.456789, "123.456789") 130 }