Skip to content

Commit

Permalink
Implement Optimized NewFromFloatWithExponent
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandrosKyriakakis committed Jan 30, 2025
1 parent 3cb6b40 commit 22b11a2
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 5 deletions.
10 changes: 9 additions & 1 deletion decimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,14 +188,22 @@ func NewFromFloat32(f float32) Decimal {
return newFromDecimal(decimal.NewFromFloat32(f))
}

// fallback:
// optimized:
// NewFromFloatWithExponent converts a float64 to Decimal, with an arbitrary
// number of fractional digits.
//
// Example:
//
// NewFromFloatWithExponent(123.456, -2).String() // output: "123.46"
//
// NOTE: this will panic on NaN, +/-inf
func NewFromFloatWithExponent(value float64, exp int32) Decimal {
decimalPlaces := -exp // decimalPlaces could be 0..12 here, inclusive
formatted := strconv.FormatFloat(value, 'f', int(decimalPlaces), 64)
if fixed, ok := parseFixed([]byte(formatted)); ok {
return Decimal{fixed: fixed}
}

return newFromDecimal(decimal.NewFromFloatWithExponent(value, exp))
}

Expand Down
50 changes: 46 additions & 4 deletions decimal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,54 @@ func TestDecimal(t *testing.T) {
})

t.Run("NewFromFloatWithExponent", func(t *testing.T) {
input := 123.456
{
input := 123.456

x := alpacadecimal.NewFromFloatWithExponent(input, -2)
y := decimal.NewFromFloatWithExponent(input, -2)
x := alpacadecimal.NewFromFloatWithExponent(input, -2)
y := decimal.NewFromFloatWithExponent(input, -2)

require.Equal(t, x.String(), y.String())
require.Equal(t, x.String(), y.String())
require.True(t, x.IsOptimized())
}

{
input := 123.4567890192214

x := alpacadecimal.NewFromFloatWithExponent(input, -12)
y := decimal.NewFromFloatWithExponent(input, -12)

require.Equal(t, x.String(), y.String())
require.True(t, x.IsOptimized())
}

{
input := 123.4567890192214

x := alpacadecimal.NewFromFloatWithExponent(input, -14)
y := decimal.NewFromFloatWithExponent(input, -14)

require.Equal(t, x.String(), y.String())
require.False(t, x.IsOptimized())
}

{
input := 1_123_123.4567890192214

x := alpacadecimal.NewFromFloatWithExponent(input, -12)
y := decimal.NewFromFloatWithExponent(input, -12)

require.Equal(t, x.String(), y.String())
require.True(t, x.IsOptimized())
}
{
input := 9_323_123.4567890192214 // max support decimal is 9_223_372.000_000_000_000

x := alpacadecimal.NewFromFloatWithExponent(input, -12)
y := decimal.NewFromFloatWithExponent(input, -12)

require.Equal(t, x.String(), y.String())
require.False(t, x.IsOptimized())
}
})

t.Run("NewFromFormattedString", func(t *testing.T) {
Expand Down

0 comments on commit 22b11a2

Please sign in to comment.