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  }