Esempio n. 1
0
// makeDecimalFromMandE reconstructs the decimal from the mantissa M and
// exponent E.
func makeDecimalFromMandE(negative bool, e int, m []byte, tmp []byte) decimal.Decimal {
	// ±dddd.
	b := tmp[:0]
	if n := len(m)*2 + 1; cap(b) < n {
		b = make([]byte, 0, n)
	}
	if negative {
		b = append(b, '-')
	}
	for i, v := range m {
		t := int(v)
		if i == len(m) {
			t--
		}
		t /= 2
		b = append(b, byte(t/10)+'0', byte(t%10)+'0')
	}

	// We unsafely convert the []byte to a string to avoid the usual allocation
	// when converting to a string.
	bi := new(big.Int)
	bi, ok := bi.SetString(*(*string)(unsafe.Pointer(&b)), 10)
	if !ok {
		panic("could not set big.Int's string value")
	}

	exp := 2*e - len(b)
	if negative {
		exp++
	}

	return decimal.NewFromBigInt(bi, int32(exp))
}
Esempio n. 2
0
// GetDecimal decodes a decimal value from the bytes of the receiver. If the
// tag is not DECIMAL an error will be returned.
func (v Value) GetDecimal() (decimal.Decimal, error) {
	if tag := v.GetTag(); tag != ValueType_DECIMAL {
		return decimal.Decimal{}, fmt.Errorf("value type is not %s: %s", ValueType_DECIMAL, tag)
	}
	data := v.dataBytes()
	i, n := binary.Varint(data)
	if n <= 0 {
		return decimal.Decimal{}, fmt.Errorf("int64 varint decoding failed: %d", n)
	}
	bi := new(big.Int)
	err := bi.GobDecode(data[n:])
	if err != nil {
		return decimal.Decimal{}, err
	}
	return decimal.NewFromBigInt(bi, int32(i)), nil
}