Skip to content
This repository has been archived by the owner on Feb 1, 2024. It is now read-only.

Commit

Permalink
improve function number.AsRatio(), closes #163 (#164)
Browse files Browse the repository at this point in the history
  • Loading branch information
nikhilsaraf authored May 1, 2019
1 parent 914dea2 commit 5d33101
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
19 changes: 15 additions & 4 deletions model/number.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,26 @@ func (n Number) AsString() string {

// AsRatio returns an integer numerator and denominator
func (n Number) AsRatio() (int32, int32, error) {
denominator := int32(math.Pow(10, float64(n.Precision())))
denominator64 := uint64(math.Pow(10, float64(n.Precision())))

var numerator64 uint64
// add an adjustment because the computed value should not have any digits beyond the decimal
// and we want to roll over values that are not computed correctly rather than using the expensive math/big library
adjustment := 0.1
unsignedPartial := n.AsFloat() * float64(denominator64)
if n.AsFloat() < 0 {
adjustment = -0.1
unsignedPartial *= -1
}
numerator64 = uint64(unsignedPartial + 0.1)

for numerator64%10 == 0 {
numerator64 /= 10
denominator64 /= 10
}

numerator, denominator := int32(numerator64), int32(denominator64)
if n.AsFloat() < 0 {
numerator *= -1
}
numerator := int32(n.AsFloat()*float64(denominator) + adjustment)

if float64(numerator)/float64(denominator) != n.AsFloat() {
return 0, 0, fmt.Errorf("invalid conversion to a ratio probably caused by an overflow, float input: %f, numerator: %d, denominator: %d", n.AsFloat(), numerator, denominator)
Expand Down
4 changes: 4 additions & 0 deletions model/number_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,10 @@ func TestAsRatio(t *testing.T) {
n: NumberFromFloat(-0.251841, 6),
wantN: -251841,
wantD: 1000000,
}, {
n: NumberFromFloat(5274.26, 8),
wantN: 527426,
wantD: 100,
},
}

Expand Down

0 comments on commit 5d33101

Please sign in to comment.