Skip to content

Commit 751da49

Browse files
authored
fix edge cases formatting with fixed precision (#74)
Also bump to Go 1.21.
1 parent a769a4d commit 751da49

File tree

4 files changed

+65
-13
lines changed

4 files changed

+65
-13
lines changed

.github/workflows/go.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ jobs:
77
runs-on: ubuntu-latest
88
steps:
99

10-
- name: Set up Go 1.20
10+
- name: Set up Go 1.21
1111
uses: actions/setup-go@v1
1212
with:
13-
go-version: 1.20
13+
go-version: 1.21
1414
id: go
1515

1616
- name: Check out code into the Go module directory

decimal64fmt.go

+17-10
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,25 @@ func appendFrac64(buf []byte, n, limit uint64) []byte {
2222

2323
var zeros = []byte("0000000000000000")
2424

25+
func appendZeros(buf []byte, n int) []byte {
26+
if n <= 0 {
27+
return buf
28+
}
29+
l := len(zeros)
30+
for ; n > l; n -= l {
31+
buf = append(buf, zeros...)
32+
}
33+
return append(buf, zeros[:n]...)
34+
}
35+
2536
func appendFrac64Prec(buf []byte, n uint64, prec int) []byte {
37+
if prec < 0 {
38+
return buf
39+
}
2640
// Add a digit in front so strconv.AppendUint doesn't trim leading zeros.
2741
n += 10 * decimal64Base
2842
if prec < 16 {
29-
unit := powersOf10[16-prec]
43+
unit := powersOf10[max(0, 16-prec)]
3044
rem := n % unit
3145
n /= unit
3246
if rem > unit/2 || rem == unit/2 && n%2 == 1 {
@@ -40,14 +54,7 @@ func appendFrac64Prec(buf []byte, n uint64, prec int) []byte {
4054
buf = strconv.AppendUint(buf[:buflen-1], n, 10)
4155
buf[buflen-1] = prefix
4256

43-
for ; prec >= 2*decimal64Digits; prec -= decimal64Digits {
44-
buf = append(buf, zeros...)
45-
}
46-
if prec > decimal64Digits {
47-
buf = append(buf, zeros[:prec-decimal64Digits]...)
48-
}
49-
50-
return buf
57+
return appendZeros(buf, prec-decimal64Digits)
5158
}
5259

5360
func appendUint64(buf []byte, n, limit uint64) []byte {
@@ -132,7 +139,7 @@ formatBlock:
132139
buf = append(buf, '.')
133140
if exponent < 0 {
134141
p += exponent
135-
buf = append(buf, zeros[:-exponent]...)
142+
buf = appendZeros(buf, min(-exponent, prec))
136143
}
137144
buf = appendFrac64Prec(buf, frac, p)
138145
if prec == -1 {

decimal64fmt_test.go

+45
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,51 @@ func TestDecimal64FormatPrecEdgeCases(t *testing.T) {
157157
}
158158
}
159159

160+
func TestDecimal64FormatPrecEdgeCases2(t *testing.T) {
161+
t.Parallel()
162+
163+
test := func(expected string, input Decimal64, prec int) {
164+
t.Helper()
165+
data := input.Append(nil, 'f', prec)
166+
assert.Equal(t, expected, string(data))
167+
}
168+
169+
test("0.062", MustParse64("0.0625"), 3)
170+
test("10000.0000000000", MustParse64("1e4"), 10)
171+
test("10000000000.0000000000", MustParse64("1e10"), 10)
172+
test("100000000000.0000000000", MustParse64("1e11"), 10)
173+
// test("0.0000000000", MustParse64("1e50"), 10)
174+
test("0.0001000000", MustParse64("1e-4"), 10)
175+
test("0.0000000001", MustParse64("1e-10"), 10)
176+
test("0.0000000000", MustParse64("1e-11"), 10)
177+
test("0.0000000000", MustParse64("1e-20"), 10)
178+
test("0.0000000000", MustParse64("1e-30"), 10)
179+
test("0.000000000000000000000000000001", MustParse64("1e-30"), 30)
180+
test("0.0000000000", Zero64, 10)
181+
test("-0.0000000000", Zero64.NextMinus(), 10)
182+
test("0.0000000000", Zero64.NextPlus(), 10)
183+
test("inf", Infinity64, 10)
184+
test("9999999999999999000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0000000000", Infinity64.NextMinus(), 10)
185+
test("inf", Infinity64.NextPlus(), 10)
186+
187+
test("-10000.0000000000", MustParse64("-1e4"), 10)
188+
test("-10000000000.0000000000", MustParse64("-1e10"), 10)
189+
test("-100000000000.0000000000", MustParse64("-1e11"), 10)
190+
// test("-0.0000000000", MustParse64("-1e50"), 10)
191+
test("-0.0001000000", MustParse64("-1e-4"), 10)
192+
test("-0.0000000001", MustParse64("-1e-10"), 10)
193+
test("-0.0000000000", MustParse64("-1e-11"), 10)
194+
test("-0.0000000000", MustParse64("-1e-20"), 10)
195+
test("-0.0000000000", MustParse64("-1e-30"), 10)
196+
test("-0.000000000000000000000000000001", MustParse64("-1e-30"), 30)
197+
test("-0.0000000000", NegZero64, 10)
198+
test("-0.0000000000", Zero64.NextMinus(), 10)
199+
test("0.0000000000", Zero64.NextPlus(), 10)
200+
test("-inf", NegInfinity64, 10)
201+
test("-inf", NegInfinity64.NextMinus(), 10)
202+
test("-9999999999999999000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0000000000", NegInfinity64.NextPlus(), 10)
203+
}
204+
160205
func TestDecimal64FormatPrecEdgeCasesHalfAway(t *testing.T) {
161206
t.Parallel()
162207

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/anz-bank/decimal
22

3-
go 1.20
3+
go 1.21
44

55
require github.com/stretchr/testify v1.2.2
66

0 commit comments

Comments
 (0)