Skip to content

Commit

Permalink
Fix fraction precision loss
Browse files Browse the repository at this point in the history
  • Loading branch information
ohler55 committed Dec 26, 2024
1 parent 990adf5 commit da539f7
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

The structure and content of this file follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [1.25.1] - 2024-12-26
### Fixed
- Fixed precision loss with some fraction parsing.

## [1.25.0] - 2024-10-26
### Added
- The `Expr.Walk()` function was added. Similar to jp.Walk but walk expression matches.
Expand Down
13 changes: 12 additions & 1 deletion gen/number.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,18 @@ func (n *Number) AsNum() (num any) {
default:
f := float64(n.I)
if 0 < n.Frac {
f += float64(n.Frac) / float64(n.Div)
// Remove trailing zeros as they can cause precision loss due to
// the way go handles multiplication and division.
for 1 < n.Div && n.Frac%10 == 0 {
n.Frac /= 10
n.Div /= 10
}
// A simple division loses precision yet dividing 1.0 by the
// divisor and then multiplying the fraction seems to solve the
// issue. As a guess it might have something to do with the
// operation being in base 2 with a special case for 1.0 divided
// by a number.
f += float64(n.Frac) * (1.0 / float64(n.Div))
}
if n.Neg {
f = -f
Expand Down
8 changes: 4 additions & 4 deletions jp/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ func (f *Filter) String() string {

// Append a fragment string representation of the fragment to the buffer
// then returning the expanded buffer.
func (f Filter) Append(buf []byte, _, _ bool) []byte {
func (f *Filter) Append(buf []byte, _, _ bool) []byte {
buf = append(buf, "[?"...)
buf = f.Script.Append(buf)
buf = append(buf, ']')

return buf
}

func (f Filter) remove(value any) (out any, changed bool) {
func (f *Filter) remove(value any) (out any, changed bool) {
out = value
switch tv := value.(type) {
case []any:
Expand Down Expand Up @@ -162,7 +162,7 @@ func (f Filter) remove(value any) (out any, changed bool) {
return
}

func (f Filter) removeOne(value any) (out any, changed bool) {
func (f *Filter) removeOne(value any) (out any, changed bool) {
out = value
switch tv := value.(type) {
case []any:
Expand Down Expand Up @@ -290,7 +290,7 @@ func (f Filter) removeOne(value any) (out any, changed bool) {
return
}

func (f Filter) locate(pp Expr, data any, rest Expr, max int) (locs []Expr) {
func (f *Filter) locate(pp Expr, data any, rest Expr, max int) (locs []Expr) {
ns, lcs := f.evalWithRoot([]any{}, data, nil)
stack, _ := ns.([]any)
if len(rest) == 0 { // last one
Expand Down
4 changes: 4 additions & 0 deletions oj/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ func TestParserParseString(t *testing.T) {
{src: "123", value: 123},
{src: "-321", value: -321},
{src: "12.3", value: 12.3},
{src: "1.5693", value: 1.5693},
{src: "1.56930", value: 1.5693},
{src: "1.569300", value: 1.5693},
{src: "1.00", value: 1.0},
{src: "0 ", value: 0},
{src: "0\n", value: 0},
{src: "2e-7 ", value: 2e-7},
Expand Down

0 comments on commit da539f7

Please sign in to comment.