Source file src/internal/strconv/itoa_test.go

     1  // Copyright 2009 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 strconv_test
     6  
     7  import (
     8  	"fmt"
     9  	. "internal/strconv"
    10  	"testing"
    11  )
    12  
    13  type itob64Test struct {
    14  	in   int64
    15  	base int
    16  	out  string
    17  }
    18  
    19  var itob64tests = []itob64Test{
    20  	{0, 10, "0"},
    21  	{1, 10, "1"},
    22  	{-1, 10, "-1"},
    23  	{12345678, 10, "12345678"},
    24  	{-987654321, 10, "-987654321"},
    25  	{1<<31 - 1, 10, "2147483647"},
    26  	{-1<<31 + 1, 10, "-2147483647"},
    27  	{1 << 31, 10, "2147483648"},
    28  	{-1 << 31, 10, "-2147483648"},
    29  	{1<<31 + 1, 10, "2147483649"},
    30  	{-1<<31 - 1, 10, "-2147483649"},
    31  	{1<<32 - 1, 10, "4294967295"},
    32  	{-1<<32 + 1, 10, "-4294967295"},
    33  	{1 << 32, 10, "4294967296"},
    34  	{-1 << 32, 10, "-4294967296"},
    35  	{1<<32 + 1, 10, "4294967297"},
    36  	{-1<<32 - 1, 10, "-4294967297"},
    37  	{1 << 50, 10, "1125899906842624"},
    38  	{1<<63 - 1, 10, "9223372036854775807"},
    39  	{-1<<63 + 1, 10, "-9223372036854775807"},
    40  	{-1 << 63, 10, "-9223372036854775808"},
    41  
    42  	{0, 2, "0"},
    43  	{10, 2, "1010"},
    44  	{-1, 2, "-1"},
    45  	{1 << 15, 2, "1000000000000000"},
    46  
    47  	{-8, 8, "-10"},
    48  	{057635436545, 8, "57635436545"},
    49  	{1 << 24, 8, "100000000"},
    50  
    51  	{16, 16, "10"},
    52  	{-0x123456789abcdef, 16, "-123456789abcdef"},
    53  	{1<<63 - 1, 16, "7fffffffffffffff"},
    54  	{1<<63 - 1, 2, "111111111111111111111111111111111111111111111111111111111111111"},
    55  	{-1 << 63, 2, "-1000000000000000000000000000000000000000000000000000000000000000"},
    56  
    57  	{16, 17, "g"},
    58  	{25, 25, "10"},
    59  	{(((((17*35+24)*35+21)*35+34)*35+12)*35+24)*35 + 32, 35, "holycow"},
    60  	{(((((17*36+24)*36+21)*36+34)*36+12)*36+24)*36 + 32, 36, "holycow"},
    61  }
    62  
    63  func TestItoa(t *testing.T) {
    64  	for _, test := range itob64tests {
    65  		s := FormatInt(test.in, test.base)
    66  		if s != test.out {
    67  			t.Errorf("FormatInt(%v, %v) = %v want %v",
    68  				test.in, test.base, s, test.out)
    69  		}
    70  		x := AppendInt([]byte("abc"), test.in, test.base)
    71  		if string(x) != "abc"+test.out {
    72  			t.Errorf("AppendInt(%q, %v, %v) = %q want %v",
    73  				"abc", test.in, test.base, x, test.out)
    74  		}
    75  
    76  		if test.in >= 0 {
    77  			s := FormatUint(uint64(test.in), test.base)
    78  			if s != test.out {
    79  				t.Errorf("FormatUint(%v, %v) = %v want %v",
    80  					test.in, test.base, s, test.out)
    81  			}
    82  			x := AppendUint(nil, uint64(test.in), test.base)
    83  			if string(x) != test.out {
    84  				t.Errorf("AppendUint(%q, %v, %v) = %q want %v",
    85  					"abc", uint64(test.in), test.base, x, test.out)
    86  			}
    87  		}
    88  
    89  		if test.base == 10 && test.in >= 0 {
    90  			buf := make([]byte, 32)
    91  			i := RuntimeFormatBase10(buf[:], uint64(test.in))
    92  			s := string(buf[i:])
    93  			if s != test.out {
    94  				t.Errorf("RuntimeFormatBase10(%d) = %q, want %q", test.in, s, test.out)
    95  			}
    96  		}
    97  
    98  		if test.base == 10 && int64(int(test.in)) == test.in {
    99  			s := Itoa(int(test.in))
   100  			if s != test.out {
   101  				t.Errorf("Itoa(%v) = %v want %v",
   102  					test.in, s, test.out)
   103  			}
   104  		}
   105  	}
   106  
   107  	// Override when base is illegal
   108  	defer func() {
   109  		if r := recover(); r == nil {
   110  			t.Fatalf("expected panic due to illegal base")
   111  		}
   112  	}()
   113  	FormatUint(12345678, 1)
   114  }
   115  
   116  type uitob64Test struct {
   117  	in   uint64
   118  	base int
   119  	out  string
   120  }
   121  
   122  var uitob64tests = []uitob64Test{
   123  	{1<<63 - 1, 10, "9223372036854775807"},
   124  	{1 << 63, 10, "9223372036854775808"},
   125  	{1<<63 + 1, 10, "9223372036854775809"},
   126  	{1<<64 - 2, 10, "18446744073709551614"},
   127  	{1<<64 - 1, 10, "18446744073709551615"},
   128  	{1<<64 - 1, 2, "1111111111111111111111111111111111111111111111111111111111111111"},
   129  }
   130  
   131  func TestUitoa(t *testing.T) {
   132  	for _, test := range uitob64tests {
   133  		s := FormatUint(test.in, test.base)
   134  		if s != test.out {
   135  			t.Errorf("FormatUint(%v, %v) = %v want %v",
   136  				test.in, test.base, s, test.out)
   137  		}
   138  		x := AppendUint([]byte("abc"), test.in, test.base)
   139  		if string(x) != "abc"+test.out {
   140  			t.Errorf("AppendUint(%q, %v, %v) = %q want %v",
   141  				"abc", test.in, test.base, x, test.out)
   142  		}
   143  		if test.base == 10 {
   144  			buf := make([]byte, 32)
   145  			i := RuntimeFormatBase10(buf[:], test.in)
   146  			s := string(buf[i:])
   147  			if s != test.out {
   148  				t.Errorf("RuntimeFormatBase10(%d) = %q, want %q", test.in, s, test.out)
   149  			}
   150  		}
   151  	}
   152  }
   153  
   154  var varlenUints = []struct {
   155  	in  uint64
   156  	out string
   157  }{
   158  	{1, "1"},
   159  	{12, "12"},
   160  	{123, "123"},
   161  	{1234, "1234"},
   162  	{12345, "12345"},
   163  	{123456, "123456"},
   164  	{1234567, "1234567"},
   165  	{12345678, "12345678"},
   166  	{123456789, "123456789"},
   167  	{1234567890, "1234567890"},
   168  	{12345678901, "12345678901"},
   169  	{123456789012, "123456789012"},
   170  	{1234567890123, "1234567890123"},
   171  	{12345678901234, "12345678901234"},
   172  	{123456789012345, "123456789012345"},
   173  	{1234567890123456, "1234567890123456"},
   174  	{12345678901234567, "12345678901234567"},
   175  	{123456789012345678, "123456789012345678"},
   176  	{1234567890123456789, "1234567890123456789"},
   177  	{12345678901234567890, "12345678901234567890"},
   178  }
   179  
   180  func TestFormatUintVarlen(t *testing.T) {
   181  	for _, test := range varlenUints {
   182  		s := FormatUint(test.in, 10)
   183  		if s != test.out {
   184  			t.Errorf("FormatUint(%v, 10) = %v want %v", test.in, s, test.out)
   185  		}
   186  	}
   187  }
   188  
   189  func BenchmarkFormatInt(b *testing.B) {
   190  	for i := 0; i < b.N; i++ {
   191  		for _, test := range itob64tests {
   192  			s := FormatInt(test.in, test.base)
   193  			BenchSink += len(s)
   194  		}
   195  	}
   196  }
   197  
   198  func BenchmarkAppendInt(b *testing.B) {
   199  	dst := make([]byte, 0, 30)
   200  	for i := 0; i < b.N; i++ {
   201  		for _, test := range itob64tests {
   202  			dst = AppendInt(dst[:0], test.in, test.base)
   203  			BenchSink += len(dst)
   204  		}
   205  	}
   206  }
   207  
   208  func BenchmarkFormatUint(b *testing.B) {
   209  	for i := 0; i < b.N; i++ {
   210  		for _, test := range uitob64tests {
   211  			s := FormatUint(test.in, test.base)
   212  			BenchSink += len(s)
   213  		}
   214  	}
   215  }
   216  
   217  func BenchmarkAppendUint(b *testing.B) {
   218  	dst := make([]byte, 0, 30)
   219  	for i := 0; i < b.N; i++ {
   220  		for _, test := range uitob64tests {
   221  			dst = AppendUint(dst[:0], test.in, test.base)
   222  			BenchSink += len(dst)
   223  		}
   224  	}
   225  }
   226  
   227  func BenchmarkFormatIntSmall(b *testing.B) {
   228  	smallInts := []int64{7, 42}
   229  	for _, smallInt := range smallInts {
   230  		b.Run(Itoa(int(smallInt)), func(b *testing.B) {
   231  			for i := 0; i < b.N; i++ {
   232  				s := FormatInt(smallInt, 10)
   233  				BenchSink += len(s)
   234  			}
   235  		})
   236  	}
   237  }
   238  
   239  func BenchmarkAppendIntSmall(b *testing.B) {
   240  	dst := make([]byte, 0, 30)
   241  	const smallInt = 42
   242  	for i := 0; i < b.N; i++ {
   243  		dst = AppendInt(dst[:0], smallInt, 10)
   244  		BenchSink += len(dst)
   245  	}
   246  }
   247  
   248  func BenchmarkAppendUintVarlen(b *testing.B) {
   249  	for _, test := range varlenUints {
   250  		b.Run(fmt.Sprint("digits=", len(test.out)), func(b *testing.B) {
   251  			dst := make([]byte, 0, 30)
   252  			for j := 0; j < b.N; j++ {
   253  				dst = AppendUint(dst[:0], test.in, 10)
   254  				BenchSink += len(dst)
   255  			}
   256  		})
   257  	}
   258  }
   259  
   260  var BenchSink int // make sure compiler cannot optimize away benchmarks
   261  

View as plain text