Skip to content

Commit 57d420f

Browse files
authored
Merge pull request #1098 from c9s/fix/precision/format-string
FIX: fix format string float point issue
2 parents 94828e6 + 51a52d1 commit 57d420f

File tree

3 files changed

+113
-4
lines changed

3 files changed

+113
-4
lines changed

pkg/fixedpoint/convert.go

+44-3
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,50 @@ func (v Value) FormatString(prec int) string {
115115
} else if v == NegInf {
116116
return "-inf"
117117
}
118-
pow := math.Pow10(prec)
119-
return strconv.FormatFloat(
120-
math.Trunc(float64(v)/DefaultPow*pow)/pow, 'f', prec, 64)
118+
119+
u := int64(v)
120+
121+
// trunc precision
122+
precDiff := DefaultPrecision - prec
123+
if precDiff > 0 {
124+
powDiff := int64(math.Round(math.Pow10(precDiff)))
125+
u = int64(v) / powDiff * powDiff
126+
}
127+
128+
// check sign
129+
sign := Value(u).Sign()
130+
131+
basePow := int64(DefaultPow)
132+
a := u / basePow
133+
b := u % basePow
134+
135+
if a < 0 {
136+
a = -a
137+
}
138+
139+
if b < 0 {
140+
b = -b
141+
}
142+
143+
str := strconv.FormatInt(a, 10)
144+
if prec > 0 {
145+
bStr := fmt.Sprintf(".%08d", b)
146+
if prec <= DefaultPrecision {
147+
bStr = bStr[0 : prec+1]
148+
} else {
149+
for i := prec - DefaultPrecision; i > 0; i-- {
150+
bStr += "0"
151+
}
152+
}
153+
154+
str += bStr
155+
}
156+
157+
if sign < 0 {
158+
str = "-" + str
159+
}
160+
161+
return str
121162
}
122163

123164
func (v Value) Percentage() string {

pkg/fixedpoint/convert_test.go

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package fixedpoint
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func Test_FormatString(t *testing.T) {
10+
assert := assert.New(t)
11+
12+
t.Run("0.57 with prec = 5, expected 0.57", func(t *testing.T) {
13+
v := MustNewFromString("0.57")
14+
s := v.FormatString(5)
15+
assert.Equal("0.57000", s)
16+
})
17+
18+
t.Run("0.57123456 with prec = 5, expected 0.57123", func(t *testing.T) {
19+
v := MustNewFromString("0.57123456")
20+
s := v.FormatString(5)
21+
assert.Equal("0.57123", s)
22+
})
23+
24+
t.Run("1.23456789 with prec = 9, expected 1.23456789", func(t *testing.T) {
25+
v := MustNewFromString("1.23456789")
26+
s := v.FormatString(9)
27+
assert.Equal("1.234567890", s)
28+
})
29+
30+
t.Run("1.02345678 with prec = 9, expected 1.02345678", func(t *testing.T) {
31+
v := MustNewFromString("1.02345678")
32+
s := v.FormatString(9)
33+
assert.Equal("1.023456780", s)
34+
})
35+
36+
t.Run("-0.57 with prec = 5, expected -0.57", func(t *testing.T) {
37+
v := MustNewFromString("-0.57")
38+
s := v.FormatString(5)
39+
assert.Equal("-0.57000", s)
40+
})
41+
42+
t.Run("-1.23456789 with prec = 9, expected 1.23456789", func(t *testing.T) {
43+
v := MustNewFromString("-1.23456789")
44+
s := v.FormatString(9)
45+
assert.Equal("-1.234567890", s)
46+
})
47+
48+
t.Run("-0.00001234 with prec = 3, expected = 0.000", func(t *testing.T) {
49+
v := MustNewFromString("-0.0001234")
50+
s := v.FormatString(3)
51+
assert.Equal("0.000", s)
52+
})
53+
54+
// comment out negative precision for dnum testing
55+
/*
56+
t.Run("12.3456789 with prec = -1, expected 10", func(t *testing.T) {
57+
v := MustNewFromString("12.3456789")
58+
s := v.FormatString(-1)
59+
assert.Equal("10", s)
60+
})
61+
62+
t.Run("12.3456789 with prec = -3, expected = 0", func(t *testing.T) {
63+
v := MustNewFromString("12.3456789")
64+
s := v.FormatString(-2)
65+
assert.Equal("0", s)
66+
})
67+
*/
68+
}

pkg/types/market.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ func (m Market) FormatPrice(val fixedpoint.Value) string {
113113
}
114114

115115
func FormatPrice(price fixedpoint.Value, tickSize fixedpoint.Value) string {
116-
prec := int(math.Round(math.Abs(math.Log10(tickSize.Float64()))))
116+
prec := int(math.Round(math.Log10(tickSize.Float64()) * -1.0))
117117
return price.FormatString(prec)
118118
}
119119

0 commit comments

Comments
 (0)