Home | History | Annotate | Download | only in big
      1 // Copyright 2015 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 big
      6 
      7 import (
      8 	"fmt"
      9 	"testing"
     10 )
     11 
     12 func TestDecimalString(t *testing.T) {
     13 	for _, test := range []struct {
     14 		x    decimal
     15 		want string
     16 	}{
     17 		{want: "0"},
     18 		{decimal{nil, 1000}, "0"}, // exponent of 0 is ignored
     19 		{decimal{[]byte("12345"), 0}, "0.12345"},
     20 		{decimal{[]byte("12345"), -3}, "0.00012345"},
     21 		{decimal{[]byte("12345"), +3}, "123.45"},
     22 		{decimal{[]byte("12345"), +10}, "1234500000"},
     23 	} {
     24 		if got := test.x.String(); got != test.want {
     25 			t.Errorf("%v == %s; want %s", test.x, got, test.want)
     26 		}
     27 	}
     28 }
     29 
     30 func TestDecimalInit(t *testing.T) {
     31 	for _, test := range []struct {
     32 		x     Word
     33 		shift int
     34 		want  string
     35 	}{
     36 		{0, 0, "0"},
     37 		{0, -100, "0"},
     38 		{0, 100, "0"},
     39 		{1, 0, "1"},
     40 		{1, 10, "1024"},
     41 		{1, 100, "1267650600228229401496703205376"},
     42 		{1, -100, "0.0000000000000000000000000000007888609052210118054117285652827862296732064351090230047702789306640625"},
     43 		{12345678, 8, "3160493568"},
     44 		{12345678, -8, "48225.3046875"},
     45 		{195312, 9, "99999744"},
     46 		{1953125, 9, "1000000000"},
     47 	} {
     48 		var d decimal
     49 		d.init(nat{test.x}.norm(), test.shift)
     50 		if got := d.String(); got != test.want {
     51 			t.Errorf("%d << %d == %s; want %s", test.x, test.shift, got, test.want)
     52 		}
     53 	}
     54 }
     55 
     56 func TestDecimalRounding(t *testing.T) {
     57 	for _, test := range []struct {
     58 		x              uint64
     59 		n              int
     60 		down, even, up string
     61 	}{
     62 		{0, 0, "0", "0", "0"},
     63 		{0, 1, "0", "0", "0"},
     64 
     65 		{1, 0, "0", "0", "10"},
     66 		{5, 0, "0", "0", "10"},
     67 		{9, 0, "0", "10", "10"},
     68 
     69 		{15, 1, "10", "20", "20"},
     70 		{45, 1, "40", "40", "50"},
     71 		{95, 1, "90", "100", "100"},
     72 
     73 		{12344999, 4, "12340000", "12340000", "12350000"},
     74 		{12345000, 4, "12340000", "12340000", "12350000"},
     75 		{12345001, 4, "12340000", "12350000", "12350000"},
     76 		{23454999, 4, "23450000", "23450000", "23460000"},
     77 		{23455000, 4, "23450000", "23460000", "23460000"},
     78 		{23455001, 4, "23450000", "23460000", "23460000"},
     79 
     80 		{99994999, 4, "99990000", "99990000", "100000000"},
     81 		{99995000, 4, "99990000", "100000000", "100000000"},
     82 		{99999999, 4, "99990000", "100000000", "100000000"},
     83 
     84 		{12994999, 4, "12990000", "12990000", "13000000"},
     85 		{12995000, 4, "12990000", "13000000", "13000000"},
     86 		{12999999, 4, "12990000", "13000000", "13000000"},
     87 	} {
     88 		x := nat(nil).setUint64(test.x)
     89 
     90 		var d decimal
     91 		d.init(x, 0)
     92 		d.roundDown(test.n)
     93 		if got := d.String(); got != test.down {
     94 			t.Errorf("roundDown(%d, %d) = %s; want %s", test.x, test.n, got, test.down)
     95 		}
     96 
     97 		d.init(x, 0)
     98 		d.round(test.n)
     99 		if got := d.String(); got != test.even {
    100 			t.Errorf("round(%d, %d) = %s; want %s", test.x, test.n, got, test.even)
    101 		}
    102 
    103 		d.init(x, 0)
    104 		d.roundUp(test.n)
    105 		if got := d.String(); got != test.up {
    106 			t.Errorf("roundUp(%d, %d) = %s; want %s", test.x, test.n, got, test.up)
    107 		}
    108 	}
    109 }
    110 
    111 var sink string
    112 
    113 func BenchmarkDecimalConversion(b *testing.B) {
    114 	for i := 0; i < b.N; i++ {
    115 		for shift := -100; shift <= +100; shift++ {
    116 			var d decimal
    117 			d.init(natOne, shift)
    118 			sink = d.String()
    119 		}
    120 	}
    121 }
    122 
    123 func BenchmarkFloatString(b *testing.B) {
    124 	x := new(Float)
    125 	for _, prec := range []uint{1e2, 1e3, 1e4, 1e5} {
    126 		x.SetPrec(prec).SetRat(NewRat(1, 3))
    127 		b.Run(fmt.Sprintf("%v", prec), func(b *testing.B) {
    128 			b.ReportAllocs()
    129 			for i := 0; i < b.N; i++ {
    130 				sink = x.String()
    131 			}
    132 		})
    133 	}
    134 }
    135