コード例 #1
0
ファイル: decimal_test.go プロジェクト: knz/cockroach
func TestNonsortingEncodeDecimal(t *testing.T) {
	testCases := []struct {
		Value    *inf.Dec
		Encoding []byte
	}{
		{inf.NewDec(-99122, -99999), []byte{0x1a, 0xf8, 0x01, 0x86, 0xa4, 0x01, 0x83, 0x32}},
		// Three duplicates to make sure -13*10^1000 <= -130*10^999 <= -13*10^1000
		{inf.NewDec(-13, -1000), []byte{0x1a, 0xf7, 0x03, 0xea, 0x0d}},
		{inf.NewDec(-130, -999), []byte{0x1a, 0xf7, 0x03, 0xea, 0x0d}},
		{inf.NewDec(-13, -1000), []byte{0x1a, 0xf7, 0x03, 0xea, 0x0d}},
		{decimal.NewDecFromFloat(-math.MaxFloat64), []byte{0x1a, 0xf7, 0x01, 0x35, 0x3f, 0xdd, 0xec, 0x7f, 0x2f, 0xaf, 0x35}},
		{inf.NewDec(-130, -100), []byte{0x1a, 0xef, 0x0d}},
		{inf.NewDec(-13, 0), []byte{0x1a, 0x8a, 0x0d}},
		{inf.NewDec(-11, 0), []byte{0x1a, 0x8a, 0x0b}},
		{inf.NewDec(-1, 0), []byte{0x1a, 0x89, 0x01}},
		{inf.NewDec(-8, 1), []byte{0x25, 0x08}},
		{inf.NewDec(-1, 1), []byte{0x25, 0x01}},
		{inf.NewDec(-11, 4), []byte{0x26, 0x8a, 0x0b}},
		{inf.NewDec(-11, 6), []byte{0x26, 0x8c, 0x0b}},
		{decimal.NewDecFromFloat(-math.SmallestNonzeroFloat64), []byte{0x26, 0xf7, 0x01, 0x43, 0x05}},
		{inf.NewDec(-11, 66666), []byte{0x26, 0xf8, 0x01, 0x04, 0x68, 0x0b}},
		{inf.NewDec(0, 0), []byte{0x27}},
		{decimal.NewDecFromFloat(math.SmallestNonzeroFloat64), []byte{0x28, 0xf7, 0x01, 0x43, 0x05}},
		{inf.NewDec(11, 6), []byte{0x28, 0x8c, 0x0b}},
		{inf.NewDec(11, 4), []byte{0x28, 0x8a, 0x0b}},
		{inf.NewDec(1, 1), []byte{0x29, 0x01}},
		{inf.NewDec(12345, 5), []byte{0x29, 0x30, 0x39}},
		{inf.NewDec(8, 1), []byte{0x29, 0x08}},
		{inf.NewDec(1, 0), []byte{0x34, 0x89, 0x01}},
		{inf.NewDec(11, 0), []byte{0x34, 0x8a, 0x0b}},
		{inf.NewDec(13, 0), []byte{0x34, 0x8a, 0x0d}},
		// Note that this does not sort correctly!
		{inf.NewDec(255, 0), []byte{0x34, 0x8b, 0xff}},
		{inf.NewDec(256, 0), []byte{0x34, 0x8b, 0x01, 0x00}},
		{decimal.NewDecFromFloat(math.MaxFloat64), []byte{0x34, 0xf7, 0x01, 0x35, 0x3f, 0xdd, 0xec, 0x7f, 0x2f, 0xaf, 0x35}},
		// Four duplicates to make sure 13*10^1000 <= 130*10^999 <= 1300*10^998 <= 13*10^1000
		{inf.NewDec(13, -1000), []byte{0x34, 0xf7, 0x03, 0xea, 0x0d}},
		{inf.NewDec(130, -999), []byte{0x34, 0xf7, 0x03, 0xea, 0x0d}},
		{inf.NewDec(1300, -998), []byte{0x34, 0xf7, 0x03, 0xea, 0x0d}},
		{inf.NewDec(13, -1000), []byte{0x34, 0xf7, 0x03, 0xea, 0x0d}},
		{inf.NewDec(99122, -99999), []byte{0x34, 0xf8, 0x01, 0x86, 0xa4, 0x01, 0x83, 0x32}},
		{inf.NewDec(99122839898321208, -99999), []byte{0x34, 0xf8, 0x01, 0x86, 0xb0, 0x01, 0x60, 0x27, 0xb2, 0x9d, 0x44, 0x71, 0x38}},
	}

	rng, _ := randutil.NewPseudoRand()

	for _, tmp := range [][]byte{nil, make([]byte, 0, 100)} {
		for i, c := range testCases {
			enc := EncodeNonsortingDecimal(nil, c.Value)
			dec, err := DecodeNonsortingDecimal(enc, tmp)
			if err != nil {
				t.Error(err)
				continue
			}
			if !bytes.Equal(enc, c.Encoding) {
				t.Errorf("unexpected mismatch for %s. expected [% x], got [% x]",
					c.Value, c.Encoding, enc)
			}
			if dec.Cmp(c.Value) != 0 {
				t.Errorf("%d unexpected mismatch for %v. got %v", i, c.Value, dec)
			}
			// Test that appending the decimal to an existing buffer works. It
			// is important to test with various values, slice lengths, and
			// capacities because the various encoding paths try to use any
			// spare capacity to avoid allocations.
			for trials := 0; trials < 5; trials++ {
				orig := randBuf(rng, 30)
				origLen := len(orig)

				bufCap := origLen + rng.Intn(30)
				buf := make([]byte, origLen, bufCap)
				copy(buf, orig)

				enc := EncodeNonsortingDecimal(buf, c.Value)
				dec, err := DecodeNonsortingDecimal(enc[origLen:], tmp)
				if err != nil {
					t.Fatal(err)
				}

				if dec.Cmp(c.Value) != 0 {
					t.Errorf("unexpected mismatch for %v. got %v", c.Value, dec)
				}
				// Verify the existing values weren't modified.
				for i := range orig {
					if enc[i] != orig[i] {
						t.Errorf("existing byte %d changed after encoding (from %d to %d)",
							i, orig[i], enc[i])
					}
				}
			}
		}
	}
}
コード例 #2
0
ファイル: decimal_test.go プロジェクト: knz/cockroach
// randDecimal generates a random decimal with exponent in the
// range [minExp, maxExp].
func randDecimal(rng *rand.Rand, minExp, maxExp int) *inf.Dec {
	exp := randutil.RandIntInRange(rng, minExp, maxExp+1)
	// Transform random float in [0, 1) to [-1, 1) and multiply by 10^exp.
	floatVal := (rng.Float64()*2 - 1) * math.Pow10(exp)
	return decimal.NewDecFromFloat(floatVal)
}
コード例 #3
0
ファイル: decimal_test.go プロジェクト: knz/cockroach
func TestEncodeDecimal(t *testing.T) {
	testCases := []struct {
		Value    *inf.Dec
		Encoding []byte
	}{
		{inf.NewDec(-99122, -99999), []byte{0x1a, 0x86, 0x3c, 0xad, 0x38, 0xe6, 0xd7, 0x00}},
		// Three duplicates to make sure -13*10^1000 <= -130*10^999 <= -13*10^1000
		{inf.NewDec(-13, -1000), []byte{0x1a, 0x86, 0xfe, 0x0a, 0xe5, 0x00}},
		{inf.NewDec(-130, -999), []byte{0x1a, 0x86, 0xfe, 0x0a, 0xe5, 0x00}},
		{inf.NewDec(-13, -1000), []byte{0x1a, 0x86, 0xfe, 0x0a, 0xe5, 0x00}},
		{decimal.NewDecFromFloat(-math.MaxFloat64), []byte{0x1a, 0x87, 0x64, 0xfc, 0x60, 0x66, 0x44, 0xe4, 0x9e, 0x82, 0xc0, 0x8d, 0x00}},
		{inf.NewDec(-130, -100), []byte{0x1a, 0x87, 0xcb, 0xfc, 0xc3, 0x00}},
		{inf.NewDec(-13, 0), []byte{0x24, 0xe5, 0x00}},
		{inf.NewDec(-11, 0), []byte{0x24, 0xe9, 0x00}},
		{mustDecimal("-10.123456789"), []byte{0x24, 0xea, 0xe6, 0xba, 0x8e, 0x62, 0x4b, 0x00}},
		{mustDecimal("-10"), []byte{0x24, 0xeb, 0x00}},
		{mustDecimal("-9.123456789"), []byte{0x24, 0xec, 0xe6, 0xba, 0x8e, 0x62, 0x4b, 0x00}},
		{mustDecimal("-9"), []byte{0x24, 0xed, 0x00}},
		{mustDecimal("-1.1"), []byte{0x24, 0xfc, 0xeb, 0x00}},
		{inf.NewDec(-1, 0), []byte{0x24, 0xfd, 0x00}},
		{inf.NewDec(-8, 1), []byte{0x25, 0x5f, 0x00}},
		{inf.NewDec(-1, 1), []byte{0x25, 0xeb, 0x00}},
		{mustDecimal("-.09"), []byte{0x25, 0xed, 0x00}},
		{mustDecimal("-.054321"), []byte{0x25, 0xf4, 0xa8, 0xd5, 0x00}},
		{mustDecimal("-.012"), []byte{0x25, 0xfc, 0xd7, 0x00}},
		{inf.NewDec(-11, 4), []byte{0x26, 0x89, 0xe9, 0x00}},
		{inf.NewDec(-11, 6), []byte{0x26, 0x8a, 0xe9, 0x00}},
		{decimal.NewDecFromFloat(-math.SmallestNonzeroFloat64), []byte{0x26, 0xf6, 0xa1, 0xf5, 0x00}},
		{inf.NewDec(-11, 66666), []byte{0x26, 0xf7, 0x82, 0x34, 0xe9, 0x00}},
		{inf.NewDec(0, 0), []byte{0x27}},
		{decimal.NewDecFromFloat(math.SmallestNonzeroFloat64), []byte{0x28, 0x87, 0x5e, 0x0a, 0x00}},
		{inf.NewDec(11, 6), []byte{0x28, 0x87, 0xfd, 0x16, 0x00}},
		{inf.NewDec(11, 4), []byte{0x28, 0x87, 0xfe, 0x16, 0x00}},
		{inf.NewDec(1, 1), []byte{0x29, 0x14, 0x00}},
		{inf.NewDec(8, 1), []byte{0x29, 0xa0, 0x00}},
		{inf.NewDec(1, 0), []byte{0x2a, 0x02, 0x00}},
		{mustDecimal("1.1"), []byte{0x2a, 0x03, 0x14, 0x00}},
		{inf.NewDec(11, 0), []byte{0x2a, 0x16, 0x00}},
		{inf.NewDec(13, 0), []byte{0x2a, 0x1a, 0x00}},
		{decimal.NewDecFromFloat(math.MaxFloat64), []byte{0x34, 0xf6, 0x9b, 0x03, 0x9f, 0x99, 0xbb, 0x1b, 0x61, 0x7d, 0x3f, 0x72, 0x00}},
		// Four duplicates to make sure 13*10^1000 <= 130*10^999 <= 1300*10^998 <= 13*10^1000
		{inf.NewDec(13, -1000), []byte{0x34, 0xf7, 0x01, 0xf5, 0x1a, 0x00}},
		{inf.NewDec(130, -999), []byte{0x34, 0xf7, 0x01, 0xf5, 0x1a, 0x00}},
		{inf.NewDec(1300, -998), []byte{0x34, 0xf7, 0x01, 0xf5, 0x1a, 0x00}},
		{inf.NewDec(13, -1000), []byte{0x34, 0xf7, 0x01, 0xf5, 0x1a, 0x00}},
		{inf.NewDec(99122, -99999), []byte{0x34, 0xf7, 0xc3, 0x52, 0xc7, 0x19, 0x28, 0x00}},
		{inf.NewDec(99122839898321208, -99999), []byte{0x34, 0xf7, 0xc3, 0x58, 0xc7, 0x19, 0x39, 0x4f, 0xb3, 0xa7, 0x2b, 0x29, 0xa0, 0x00}},
	}

	rng, _ := randutil.NewPseudoRand()

	var lastEncoded []byte
	for _, dir := range []Direction{Ascending, Descending} {
		for _, tmp := range [][]byte{nil, make([]byte, 0, 100)} {
			for i, c := range testCases {
				enc := encodeDecimalWithDir(dir, nil, c.Value)
				_, dec := decodeDecimalWithDir(t, dir, enc, tmp)
				if dir == Ascending && !bytes.Equal(enc, c.Encoding) {
					t.Errorf("unexpected mismatch for %s. expected [% x], got [% x]",
						c.Value, c.Encoding, enc)
				}
				if i > 0 {
					if (bytes.Compare(lastEncoded, enc) > 0 && dir == Ascending) ||
						(bytes.Compare(lastEncoded, enc) < 0 && dir == Descending) {
						t.Errorf("%v: expected [% x] to be less than or equal to [% x]",
							c.Value, testCases[i-1].Encoding, enc)
					}
				}
				testPeekLength(t, enc)
				if dec.Cmp(c.Value) != 0 {
					t.Errorf("%d unexpected mismatch for %v. got %v", i, c.Value, dec)
				}
				lastEncoded = enc

				// Test that appending the decimal to an existing buffer works. It
				// is important to test with various values, slice lengths, and
				// capacities because the various encoding paths try to use any
				// spare capacity to avoid allocations.
				for trials := 0; trials < 5; trials++ {
					orig := randBuf(rng, 30)
					origLen := len(orig)

					bufCap := origLen + rng.Intn(30)
					buf := make([]byte, origLen, bufCap)
					copy(buf, orig)

					enc := encodeDecimalWithDir(dir, buf, c.Value)
					// Append some random bytes
					enc = append(enc, randBuf(rng, 20)...)
					_, dec := decodeDecimalWithDir(t, dir, enc[origLen:], tmp)

					if dec.Cmp(c.Value) != 0 {
						t.Errorf("unexpected mismatch for %v. got %v", c.Value, dec)
					}
					// Verify the existing values weren't modified.
					for i := range orig {
						if enc[i] != orig[i] {
							t.Errorf("existing byte %d changed after encoding (from %d to %d)",
								i, orig[i], enc[i])
						}
					}
				}
			}
		}
	}
}