Add infinity support for Numeric Set/Get

non-blocking
Jim Tsao 2021-10-31 12:35:35 +01:00 committed by Jack Christensen
parent a29019de9d
commit e0f9fc5212
2 changed files with 28 additions and 4 deletions

View File

@ -49,10 +49,11 @@ var bigNBaseX3 *big.Int = big.NewInt(nbase * nbase * nbase)
var bigNBaseX4 *big.Int = big.NewInt(nbase * nbase * nbase * nbase)
type Numeric struct {
Int *big.Int
Exp int32
Status Status
NaN bool
Int *big.Int
Exp int32
Status Status
NaN bool
InfinityModifier InfinityModifier
}
func (dst *Numeric) Set(src interface{}) error {
@ -73,6 +74,12 @@ func (dst *Numeric) Set(src interface{}) error {
if math.IsNaN(float64(value)) {
*dst = Numeric{Status: Present, NaN: true}
return nil
} else if math.IsInf(float64(value), 1) {
*dst = Numeric{Status: Present, InfinityModifier: Infinity}
return nil
} else if math.IsInf(float64(value), -1) {
*dst = Numeric{Status: Present, InfinityModifier: NegativeInfinity}
return nil
}
num, exp, err := parseNumericString(strconv.FormatFloat(float64(value), 'f', -1, 64))
if err != nil {
@ -83,6 +90,12 @@ func (dst *Numeric) Set(src interface{}) error {
if math.IsNaN(value) {
*dst = Numeric{Status: Present, NaN: true}
return nil
} else if math.IsInf(value, 1) {
*dst = Numeric{Status: Present, InfinityModifier: Infinity}
return nil
} else if math.IsInf(value, -1) {
*dst = Numeric{Status: Present, InfinityModifier: NegativeInfinity}
return nil
}
num, exp, err := parseNumericString(strconv.FormatFloat(value, 'f', -1, 64))
if err != nil {
@ -193,6 +206,8 @@ func (dst *Numeric) Set(src interface{}) error {
} else {
return dst.Set(*value)
}
case InfinityModifier:
*dst = Numeric{InfinityModifier: value, Status: Present}
default:
if originalSrc, ok := underlyingNumberType(src); ok {
return dst.Set(originalSrc)
@ -206,6 +221,9 @@ func (dst *Numeric) Set(src interface{}) error {
func (dst Numeric) Get() interface{} {
switch dst.Status {
case Present:
if dst.InfinityModifier != None {
return dst.InfinityModifier
}
return dst
case Null:
return nil

View File

@ -222,6 +222,12 @@ func TestNumericSet(t *testing.T) {
{source: float64(12345.678901), result: &pgtype.Numeric{Int: big.NewInt(12345678901), Exp: -6, Status: pgtype.Present}},
{source: math.NaN(), result: &pgtype.Numeric{Int: nil, Exp: 0, Status: pgtype.Present, NaN: true}},
{source: float32(math.NaN()), result: &pgtype.Numeric{Int: nil, Exp: 0, Status: pgtype.Present, NaN: true}},
{source: pgtype.Infinity, result: &pgtype.Numeric{InfinityModifier: pgtype.Infinity, Status: pgtype.Present}},
{source: math.Inf(1), result: &pgtype.Numeric{Status: pgtype.Present, InfinityModifier: pgtype.Infinity}},
{source: float32(math.Inf(1)), result: &pgtype.Numeric{Status: pgtype.Present, InfinityModifier: pgtype.Infinity}},
{source: pgtype.NegativeInfinity, result: &pgtype.Numeric{InfinityModifier: pgtype.NegativeInfinity, Status: pgtype.Present}},
{source: math.Inf(-1), result: &pgtype.Numeric{Status: pgtype.Present, InfinityModifier: pgtype.NegativeInfinity}},
{source: float32(math.Inf(1)), result: &pgtype.Numeric{Status: pgtype.Present, InfinityModifier: pgtype.Infinity}},
}
for i, tt := range successfulTests {