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

Commit 5d33101

Browse files
authored
improve function number.AsRatio(), closes #163 (#164)
1 parent 914dea2 commit 5d33101

2 files changed

Lines changed: 19 additions & 4 deletions

File tree

model/number.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,26 @@ func (n Number) AsString() string {
3939

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

44+
var numerator64 uint64
4445
// add an adjustment because the computed value should not have any digits beyond the decimal
4546
// and we want to roll over values that are not computed correctly rather than using the expensive math/big library
46-
adjustment := 0.1
47+
unsignedPartial := n.AsFloat() * float64(denominator64)
4748
if n.AsFloat() < 0 {
48-
adjustment = -0.1
49+
unsignedPartial *= -1
50+
}
51+
numerator64 = uint64(unsignedPartial + 0.1)
52+
53+
for numerator64%10 == 0 {
54+
numerator64 /= 10
55+
denominator64 /= 10
56+
}
57+
58+
numerator, denominator := int32(numerator64), int32(denominator64)
59+
if n.AsFloat() < 0 {
60+
numerator *= -1
4961
}
50-
numerator := int32(n.AsFloat()*float64(denominator) + adjustment)
5162

5263
if float64(numerator)/float64(denominator) != n.AsFloat() {
5364
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)

model/number_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,10 @@ func TestAsRatio(t *testing.T) {
287287
n: NumberFromFloat(-0.251841, 6),
288288
wantN: -251841,
289289
wantD: 1000000,
290+
}, {
291+
n: NumberFromFloat(5274.26, 8),
292+
wantN: 527426,
293+
wantD: 100,
290294
},
291295
}
292296

0 commit comments

Comments
 (0)