You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dorm/vendor/github.com/godror/godror/number.go

127 lines
4.0 KiB

// Copyright 2020 The Godror Authors
// Copyright 2016 Tamás Gulácsi
//
//
// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0
package godror
import (
"math/big"
"strings"
)
// Decompose returns the internal decimal state in parts.
// If the provided buf has sufficient capacity, buf may be returned as the coefficient with
// the value set and length set as appropriate.
func (N Number) Decompose(buf []byte) (form byte, negative bool, coefficient []byte, exponent int32) {
s := string(N)
mexp := strings.IndexByte(s, '.')
if mexp >= 0 {
s = s[:mexp] + s[mexp+1:]
exponent = -int32(len(s) - mexp)
}
var i big.Int
if _, ok := i.SetString(s, 10); !ok {
return 2, false, nil, 0
}
switch i.Sign() {
case 0:
return 0, false, nil, 0
case -1:
negative = true
}
c := (i.BitLen() + 7) >> 3
if c <= cap(buf) {
buf = buf[:c]
} else {
buf = make([]byte, c)
}
return 0, negative, i.FillBytes(buf), exponent
}
// Compose sets the internal decimal value from parts. If the value cannot be
// represented then an error should be returned.
func (N *Number) Compose(form byte, negative bool, coefficient []byte, exponent int32) error {
var i big.Int
var start int
length := 1 + len(coefficient)*3
if negative {
start = 1
}
if exponent < 0 {
length++
} else if exponent > 0 {
length += int(exponent)
}
p := make([]byte, start, length)
if start != 0 {
p[0] = '-'
}
i.SetBytes(coefficient)
p = i.Append(p, 10)
for ; exponent > 0; exponent-- {
p = append(p, '0')
}
if exponent < 0 {
exp := int(-exponent)
if plus := exp - len(p) + start + 1; plus > 0 {
olen := len(p)
p = append(p, make([]byte, plus+1)...)
copy(p[start+1+plus:], p[start:olen])
for i := 0; i < plus; i++ {
p[start+1+i] = '0'
}
p[start] = '0'
p[start+1] = '.'
} else {
p = append(p, p[len(p)-1])
copy(p[len(p)-1-exp:len(p)-1], p[len(p)-1-exp-1:len(p)-1-1])
p[len(p)-1-exp] = '.'
}
}
*N = Number(string(p))
return nil
}
var _ = decimal((*Number)(nil))
// decimal composes or decomposes a decimal value to and from individual parts.
// There are four parts: a boolean negative flag, a form byte with three possible states
// (finite=0, infinite=1, NaN=2), a base-2 big-endian integer
// coefficient (also known as a significand) as a []byte, and an int32 exponent.
// These are composed into a final value as "decimal = (neg) (form=finite) coefficient * 10 ^ exponent".
// A zero length coefficient is a zero value.
// The big-endian integer coefficient stores the most significant byte first (at coefficient[0]).
// If the form is not finite the coefficient and exponent should be ignored.
// The negative parameter may be set to true for any form, although implementations are not required
// to respect the negative parameter in the non-finite form.
//
// Implementations may choose to set the negative parameter to true on a zero or NaN value,
// but implementations that do not differentiate between negative and positive
// zero or NaN values should ignore the negative parameter without error.
// If an implementation does not support Infinity it may be converted into a NaN without error.
// If a value is set that is larger than what is supported by an implementation,
// an error must be returned.
// Implementations must return an error if a NaN or Infinity is attempted to be set while neither
// are supported.
//
// NOTE(kardianos): This is an experimental interface. See https://golang.org/issue/30870
type decimal interface {
decimalDecompose
decimalCompose
}
type decimalDecompose interface {
// Decompose returns the internal decimal state into parts.
// If the provided buf has sufficient capacity, buf may be returned as the coefficient with
// the value set and length set as appropriate.
Decompose(buf []byte) (form byte, negative bool, coefficient []byte, exponent int32)
}
type decimalCompose interface {
// Compose sets the internal decimal value from parts. If the value cannot be
// represented then an error should be returned.
Compose(form byte, negative bool, coefficient []byte, exponent int32) error
}