Ejemplo n.º 1
0
// QuadToString returns the string representation of a Quad number.
// It calls the C function QuadToString of the original decNumber package.
//
//       This function uses exponential notation quite often.
//       E.g. 0.0000001 returns "1E-7", which is often not what we want.
//
//       It is better to use the method AppendQuad() or String(), which don't use exponential notation for a wider range.
//       AppendQuad() and String() write a number without exp notation if it can be displayed with at most 34 digits, and an optional fractional point.
//
//       Zero values are signed (unlike AppendQuad and String methods):
//          -0    -->  "-0"
//          -0.00 -->  "-0.00"
//
//       Displaying "-0" is often surprising for the user. That's why AppendQuad and String methods always discard the sign of zero values.
//
func (a Quad) QuadToString() string {
	var (
		ret_str   C.Ret_str
		str_slice []byte // capacity must be exactly DecquadString
		s         string
	)

	ret_str = C.mdq_to_QuadToString(a.val) // may use exponent notation

	str_slice = pool.Get().([]byte)[:DecquadString]
	defer pool.Put(str_slice)

	for i := 0; i < int(ret_str.length); i++ {
		str_slice[i] = byte(ret_str.s[i])
	}

	s = string(str_slice[:ret_str.length])

	return s
}
Ejemplo n.º 2
0
// AppendQuad appends string representation of Quad into byte slice.
// AppendQuad and String are best to display Quad, as exponent notation is used less often than with QuadToString.
//
//       AppendQuad() writes a number without exp notation if it can be displayed with at most 34 digits, and an optional fractional point.
//       Else, falls back on QuadToString(), which will use exponential notation.
//
// See also method String(), which calls AppendQuad internally.
//
//     Zero values are always positive (unlike QuadToString method):
//          -0    -->  "0"
//          -0.00 -->  "0.00"
//
func AppendQuad(dst []byte, a Quad) []byte {
	var (
		ret_str   C.Ret_str
		str_slice []byte // length must be exactly DecquadString

		ret               C.Ret_BCD
		d                 byte
		skip_leading_zero bool = true
		inf_nan           uint32
		exp               int32
		sign              uint32
		BCD_slice         []byte // length must be exactly DecquadPmax

		buff [DecquadString]byte // enough for      sign    optional "0."    34 digits
	)

	// fill BCD array

	ret = C.mdq_to_BCD(a.val) // sign will be 1 for negative and non-zero number, else, 0. If Inf or Nan, returns an error.

	BCD_slice = pool.Get().([]byte)[:DecquadPmax]
	defer pool.Put(BCD_slice)

	for i := 0; i < DecquadPmax; i++ {
		BCD_slice[i] = byte(ret.BCD[i])
	}
	inf_nan = uint32(ret.inf_nan)
	exp = int32(ret.exp)
	sign = uint32(ret.sign)

	// if Quad value is not in 34 digits range, or Inf or Nan, we want our function to output the number, or Infinity, or NaN. Falls back on QuadToString.

	if exp > 0 || exp < -DecquadPmax || inf_nan != 0 {
		ret_str = C.mdq_to_QuadToString(a.val) // may use exponent notation

		str_slice = pool.Get().([]byte)[:DecquadString]
		defer pool.Put(str_slice)

		for i := 0; i < int(ret_str.length); i++ {
			str_slice[i] = byte(ret_str.s[i])
		}

		dst = append(dst, str_slice[:ret_str.length]...) // write buff into destination and return

		return dst
	}

	// write string. Here, the number is not Inf nor Nan.

	i := 0

	integral_part_length := len(BCD_slice) + int(exp) // here, exp is [-DecquadPmax ... 0]

	BCD_integral_part := BCD_slice[:integral_part_length]
	BCD_fractional_part := BCD_slice[integral_part_length:]

	for _, d = range BCD_integral_part { // ==== write integral part ====
		if skip_leading_zero && d == 0 {
			continue
		} else {
			skip_leading_zero = false
		}
		buff[i] = '0' + d
		i++
	}

	if i == 0 { // write '0' if no digit written for integral part
		buff[i] = '0'
		i++
	}

	if sign != 0 {
		dst = append(dst, '-') // write '-' sign if any into destination
	}

	dst = append(dst, buff[:i]...) // write integral part into destination

	if exp == 0 { // if no fractional part, just return
		return dst
	}

	dst = append(dst, '.') // ==== write fractional part ====

	i = 0
	for _, d = range BCD_fractional_part {
		buff[i] = '0' + d
		i++
	}

	dst = append(dst, buff[:i]...) // write fractional part into destination

	return dst
}