Skip to content

Commit

Permalink
decimal: implement Decimal.Scan, Decimal.Value methods
Browse files Browse the repository at this point in the history
* decimal: implement Decimal.Scan, Decimal.Value methods

* decimal: improve Decimal.Scan coverage
  • Loading branch information
eapenkin authored Aug 19, 2023
1 parent e908700 commit 9ad2f20
Show file tree
Hide file tree
Showing 10 changed files with 211 additions and 111 deletions.
16 changes: 8 additions & 8 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,26 +54,26 @@ jobs:
uses: actions/checkout@v3

- name: Run fuzzing for string conversion
run: go test -fuzztime 20s -fuzz ^FuzzDecimal_String_StringVsParse$ github.com/govalues/decimal
run: go test -fuzztime 20s -fuzz ^FuzzDecimalString$ github.com/govalues/decimal

- name: Run fuzzing for float64 conversion
run: go test -fuzztime 20s -fuzz ^FuzzDecimal_Float64_Float64VsNew$ github.com/govalues/decimal
run: go test -fuzztime 20s -fuzz ^FuzzDecimalFloat64$ github.com/govalues/decimal

- name: Run fuzzing for int64 conversion
run: go test -fuzztime 20s -fuzz ^FuzzDecimal_Int64_Int64VsNew$ github.com/govalues/decimal
run: go test -fuzztime 20s -fuzz ^FuzzDecimalInt64$ github.com/govalues/decimal

- name: Run fuzzing for addition
run: go test -fuzztime 20s -fuzz ^FuzzDecimal_Add_FintVsSint$ github.com/govalues/decimal
run: go test -fuzztime 20s -fuzz ^FuzzDecimalAdd$ github.com/govalues/decimal

- name: Run fuzzing for multiplication
run: go test -fuzztime 20s -fuzz ^FuzzDecimal_Mul_FintVsSint$ github.com/govalues/decimal
run: go test -fuzztime 20s -fuzz ^FuzzDecimalMul$ github.com/govalues/decimal

- name: Run fuzzing for fused multiply-addidtion
run: go test -fuzztime 40s -fuzz ^FuzzDecimal_FMA_FintVsSint$ github.com/govalues/decimal
run: go test -fuzztime 40s -fuzz ^FuzzDecimalFMA$ github.com/govalues/decimal

- name: Run fuzzing for division
run: go test -fuzztime 20s -fuzz ^FuzzDecimal_Quo_FintVsSint$ github.com/govalues/decimal
run: go test -fuzztime 20s -fuzz ^FuzzDecimalQuo$ github.com/govalues/decimal

- name: Run fuzzing for comparison
run: go test -fuzztime 20s -fuzz ^FuzzDecimal_Cmp_FintVsSint$ github.com/govalues/decimal
run: go test -fuzztime 20s -fuzz ^FuzzDecimalCmp$ github.com/govalues/decimal

3 changes: 3 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ linters:
- goimports
- govet
- ineffassign
- godot
- gosec
- misspell
- stylecheck
- revive
- staticcheck
- typecheck
Expand Down
57 changes: 34 additions & 23 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,61 @@
# Changelog

## [0.1.6] - 2023-08-19

### Added

- Implemented `Decimal.Scan` and `Decimal.Value`.

### Changed

- `Decimal.CopySign` treats 0 as a positive.
- Enabled `gosec`, `godot`, and `stylecheck` linters.

## [0.1.5] - 2023-08-12

### Added

- Implemented NewFromFloat64 method.
- Implemented `NewFromFloat64` method.
- Added fuzzing job to continuous integration.

### Changed

- NewFromInt64 can round to nearest if coefficient is too large.
- `NewFromInt64` can round to nearest if coefficient is too large.

## [0.1.4] - 2023-08-04

### Changed

- Implemented NewFromInt64 method.
- Implemented `NewFromInt64` method.

## [0.1.3] - 2023-08-03

### Changed

- Implemented scale argument for Decimal.Int64 method.
- Implemented scale argument for `Decimal.Int64` method.

## [0.1.2] - 2023-06-17

### Changed

- Rescale, ParseExact, MulExact, AddExact, FMAExact, and QuoExact methods
- `Rescale`, `ParseExact`, `MulExact`, `AddExact`, `FMAExact`, and `QuoExact` methods
return error if scale is out of range.

## [0.1.1] - 2023-06-10

### Changed

- New method returns error if scale is out of range.
- `New` method returns error if scale is out of range.

## [0.1.0] - 2023-06-03

### Changed

- All methods now return errors, instead of panicking.
- Implemented Decimal.Pad method.
- Implemented Decimal.PowExact method.
- Renamed Decimal.Round to Decimal.Rescale.
- Renamed Decimal.Reduce to Decimal.Trim.
- Implemented `Decimal.Pad` method.
- Implemented `Decimal.PowExact` method.
- Renamed `Decimal.Round` to `Decimal.Rescale`.
- Renamed `Decimal.Reduce` to `Decimal.Trim`.

## [0.0.13] - 2023-04-22

Expand All @@ -63,8 +74,8 @@

### Added

- Implemented Decimal.Int64 method.
- Implemented Decimal.Float64 method.
- Implemented `Decimal.Int64` method.
- Implemented `Decimal.Float64` method.

### Changed

Expand All @@ -81,35 +92,35 @@

### Added

- Implemented Decimal.One method.
- Implemented Decimal.Zero method.
- Implemented `Decimal.One` method.
- Implemented `Decimal.Zero` method.

### Changed

- Reduced memory consumption.
- Renamed Decimal.LessThanOne to Decimal.WithinOne.
- Renamed `Decimal.LessThanOne` to `Decimal.WithinOne`.

### Deleted

- Removed Decimal.WithScale.
- Removed `Decimal.WithScale`.

## [0.0.8] - 2023-03-25

### Changed

- Simplified Decimal.Quo method.
- Simplified `Decimal.Quo` method.

## [0.0.7] - 2023-03-22

### Added

- Implemented Decimal.CopySign method.
- Implemented `Decimal.CopySign` method.

## [0.0.6] - 2023-03-21

### Added

- Implemented Decimal.ULP method.
- Implemented `Decimal.ULP` method.

## [0.0.5] - 2023-03-19

Expand All @@ -122,21 +133,21 @@

### Fixed

- Fixed index out of range in Parse.
- Rounding error in Decimal.Quo.
- Fixed index out of range in `Parse`.
- Rounding error in `Decimal.Quo`.

## [0.0.3] - 2023-03-18

### Changed

- Removed errors from public API.
- Renamed Decimal.Fma to Decimal.FMA.
- Renamed `Decimal.Fma` to `Decimal.FMA`.

## [0.0.2] - 2023-03-13

### Added

- Implemented Decimal.Fma.
- Implemented `Decimal.Fma`.

## [0.0.1] - 2023-02-28

Expand Down
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
[![githubb]][github]
[![codecovb]][codecov]
[![goreportb]][goreport]
[![licenseb]][license]
[![godocb]][godoc]
[![licenseb]][license]
[![versionb]][version]

Package decimal implements immutable decimal floating-point numbers for Go.
Expand Down Expand Up @@ -61,20 +61,20 @@ pkg: github.com/govalues/benchmarks
cpu: AMD Ryzen 7 3700C with Radeon Vega Mobile Gfx
```

| Test Case | Expression | govalues | [cockroachdb] v3.1.2 | cockroachdb vs govalues | [shopspring] v1.3.1 | shopspring vs govalues |
| ------------------- | -------------------- | ---------: | -------------------: | ----------------------: | ------------------: | ---------------------: |
| Decimal_Add | 2 + 3 | 15.54n | 47.39n | +204.89% | 142.65n | +817.66% |
| Decimal_Mul | 2 * 3 | 15.87n | 61.18n | +285.51% | 136.60n | +760.74% |
| Decimal_QuoFinite | 2 / 4 | 55.95n | 360.70n | +544.74% | 654.45n | +1069.81% |
| Decimal_QuoInfinite | 2 / 3 | 570.10n | 936.40n | +64.27% | 2858.00n | +401.36% |
| Decimal_Pow | 1.1^60 | 1.01µ | 3.06µ | +202.92% | 20.09µ | +1889.90% |
| Parse | 1 | 17.35n | 88.44n | +409.74% | 132.10n | +661.38% |
| Parse | 123.456 | 36.75n | 220.15n | +499.05% | 244.45n | +565.17% |
| Parse | 123456789.1234567890 | 105.80n | 240.40n | +127.33% | 496.00n | +369.08% |
| Decimal_String | 1 | 6.39n | 23.42n | +266.32% | 237.95n | +3622.62% |
| Decimal_String | 123.456 | 37.65n | 38.27n | +1.66% | 230.40n | +512.03% |
| Decimal_String | 123456789.1234567890 | 74.95n | 189.70n | +153.10% | 324.10n | +332.42% |
| **Geometric Mean** | | **53.20n** | **164.50n** | **+209.17%** | **462.80n** | **+769.86%** |
| Test Case | Expression | govalues | [cockroachdb] v3.2.0 | cockroachdb vs govalues | [shopspring] v1.3.1 | shopspring vs govalues |
| ------------------- | -------------------- | -------: | -------------------: | ----------------------: | ------------------: | ---------------------: |
| Decimal_Add | 2 + 3 | 15.73n | 50.24n | +219.39% | 141.85n | +801.78% |
| Decimal_Mul | 2 * 3 | 15.67n | 67.34n | +329.57% | 139.55n | +790.27% |
| Decimal_QuoFinite | 2 / 4 | 61.08n | 371.35n | +508.02% | 629.70n | +931.03% |
| Decimal_QuoInfinite | 2 / 3 | 560.80n | 946.10n | +68.69% | 2736.50n | +387.92% |
| Decimal_Pow | 1.1^60 | 1.02µ | 2.89µ | +182.58% | 20.08µ | +1865.17% |
| Parse | 123456789.1234567890 | 99.16n | 219.15n | +121.01% | 480.10n | +384.17% |
| Parse | 123.456 | 37.41n | 203.80n | +444.85% | 229.20n | +512.75% |
| Parse | 1 | 16.37n | 76.27n | +365.91% | 128.90n | +687.42% |
| Decimal_String | 123456789.1234567890 | 76.47n | 215.15n | +181.35% | 329.35n | +330.69% |
| Decimal_String | 123.456 | 40.86n | 70.52n | +72.59% | 222.10n | +443.56% |
| Decimal_String | 1 | 5.32n | 19.41n | +264.88% | 192.75n | +3523.46% |
| **Geometric Mean** | | 52.70n | 170.10n | +222.71% | 445.40n | +745.22% |

The benchmark results shown in the table are provided for informational purposes only and may vary depending on your specific use case.

Expand Down
22 changes: 11 additions & 11 deletions coefficient.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,20 @@ var pow10 = [...]fint{
}

// add calculates x + y and checks overflow.
func (x fint) add(y fint) (fint, bool) {
func (x fint) add(y fint) (z fint, ok bool) {
if maxFint-x < y {
return 0, false
}
z := x + y
z = x + y
return z, true
}

// mul calculates x * y and checks overflow.
func (x fint) mul(y fint) (fint, bool) {
func (x fint) mul(y fint) (z fint, ok bool) {
if x == 0 || y == 0 {
return 0, true
}
z := x * y
z = x * y
if z/y != x {
return 0, false
}
Expand All @@ -59,11 +59,11 @@ func (x fint) mul(y fint) (fint, bool) {
}

// quo calculates x / y and checks overflow or inexact division.
func (x fint) quo(y fint) (fint, bool) {
func (x fint) quo(y fint) (z fint, ok bool) {
if y == 0 {
return 0, false
}
z := x / y
z = x / y
if y*z != x {
return 0, false
}
Expand All @@ -79,7 +79,7 @@ func (x fint) dist(y fint) fint {
}

// lsh (Left Shift) calculates x * 10^shift and checks overflow.
func (x fint) lsh(shift int) (fint, bool) {
func (x fint) lsh(shift int) (z fint, ok bool) {
// Special cases
switch {
case x == 0:
Expand All @@ -97,8 +97,8 @@ func (x fint) lsh(shift int) (fint, bool) {
}

// fsa (Fused Shift and Addition) calculates x * 10^shift + y and checks overflow.
func (x fint) fsa(shift int, y byte) (fint, bool) {
z, ok := x.lsh(shift)
func (x fint) fsa(shift int, y byte) (z fint, ok bool) {
z, ok = x.lsh(shift)
if !ok {
return 0, false
}
Expand Down Expand Up @@ -187,7 +187,7 @@ func (x fint) prec() int {
return left
}

// tzeroes returns number of trailing zeros in x
// tzeroes returns number of trailing zeros in x.
func (x fint) tzeros() int {
left, right := 1, x.prec()
for left < right {
Expand Down Expand Up @@ -362,7 +362,7 @@ func (z *sint) mul(x, y *sint) {
(*big.Int)(z).Mul((*big.Int)(x), (*big.Int)(y))
}

// quo calculates z = x / y
// quo calculates z = x / y.
func (z *sint) quo(x, y *sint) {
(*big.Int)(z).Quo((*big.Int)(x), (*big.Int)(y))
}
Expand Down
2 changes: 2 additions & 0 deletions coefficient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ func TestFint_dist(t *testing.T) {
{20, 4, 16},
{20, 3, 17},
{maxFint, 2, 9_999_999_999_999_999_997},
{maxFint, 1, 9_999_999_999_999_999_998},
{maxFint, 0, maxFint},
}
for _, tt := range cases {
x, y := tt.x, tt.y
Expand Down
Loading

0 comments on commit 9ad2f20

Please sign in to comment.