Skip to content

Commit c5bec17

Browse files
committed
exmath.Round 精度为负数时结算精准度问题 (#15)
1 parent 23f0fa7 commit c5bec17

File tree

3 files changed

+29
-7
lines changed

3 files changed

+29
-7
lines changed

exmath/benchmark/round_test.go

+13-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,19 @@ import (
77
)
88

99
func BenchmarkRound(b *testing.B) {
10-
f := 0.15807659924030304
1110
for i := 0; i < b.N; i++ {
12-
_ = exmath.Round(f, 5)
11+
_ = exmath.Round(169543.34596, 0)
12+
}
13+
}
14+
15+
func BenchmarkRoundDecimal(b *testing.B) {
16+
for i := 0; i < b.N; i++ {
17+
_ = exmath.Round(0.15807659924030304, 5)
18+
}
19+
}
20+
21+
func BenchmarkRoundInteger(b *testing.B) {
22+
for i := 0; i < b.N; i++ {
23+
_ = exmath.Round(169543.34596, -5)
1324
}
1425
}

exmath/round.go

+8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ import (
1010
// Round 四舍五入,ROUND_HALF_UP 模式实现
1111
// 返回将 val 根据指定精度 precision(十进制小数点后数字的数目)进行四舍五入的结果。precision 也可以是负数或零。
1212
func Round(val float64, precision int) float64 {
13+
if precision == 0 {
14+
return math.Round(val)
15+
}
16+
1317
p := math.Pow10(precision)
18+
if precision < 0 {
19+
return math.Floor(val*p+0.5) * math.Pow10(-precision)
20+
}
21+
1422
return math.Floor(val*p+0.5) / p
1523
}

exmath/round_test.go

+8-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package exmath
55

66
import (
7+
"fmt"
78
"math"
89
"testing"
910
)
@@ -27,11 +28,11 @@ func TestRound(t *testing.T) {
2728

2829
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2930
{1.390671161567e-309, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // denormal
30-
{0.49999999999999994, 0, 1, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5}, // 0.5-epsilon
31+
{0.49999999999999994, 0, 0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5}, // 0.5-epsilon
3132
{0.5, 0, 1, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5},
3233
{0.5000000000000001, 0, 1, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5}, // 0.5+epsilon
33-
{-1.5, 0, -1, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5},
34-
{-2.5, 0, -2, -2.5, -2.5, -2.5, -2.5, -2.5, -2.5, -2.5},
34+
{-1.5, 0, -2, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5},
35+
{-2.5, 0, -3, -2.5, -2.5, -2.5, -2.5, -2.5, -2.5, -2.5},
3536
{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()},
3637
{math.Inf(1), math.Inf(1), math.Inf(1), math.Inf(1), math.Inf(1), math.Inf(1), math.Inf(1), math.Inf(1), math.Inf(1), math.Inf(1)},
3738
}
@@ -44,14 +45,16 @@ func TestRound(t *testing.T) {
4445
{2251799813685249.5, 2251799813685249.5, 2251799813685250, 2251799813685250, 2251799813685200, 2251799813685000, 2251799813690000, 2251799813700000, 2251799814000000, 2251799810000000},
4546
{2251799813685250.5, 2251799813685250.5, 2251799813685251, 2251799813685250, 2251799813685300, 2251799813685000, 2251799813690000, 2251799813700000, 2251799814000000, 2251799810000000},
4647
{4503599627370495.5, 4503599627370495, 4503599627370496, 4503599627370500, 4503599627370500, 4503599627370000, 4503599627370000, 4503599627400000, 4503599627000000, 4503599630000000},
47-
{4503599627370497, 4503599627370497, 4503599627370498, 4503599627370500, 4503599627370500, 4503599627370000, 4503599627370000, 4503599627400000, 4503599627000000, 4503599630000000},
48+
{4503599627370497, 4503599627370497, 4503599627370497, 4503599627370500, 4503599627370500, 4503599627370000, 4503599627370000, 4503599627400000, 4503599627000000, 4503599630000000},
49+
{169543.34596, 169543.3, 169543, 169540, 169500, 170000, 170000, 200000, 0, 0},
4850
}
4951

5052
for _, cases := range vf {
5153
expected := []float64{cases.pm1, cases.p0, cases.p1, cases.p2, cases.p3, cases.p4, cases.p5, cases.p6, cases.p7}
5254
for precision := -1; precision < 8; precision++ {
5355
if actual := Round(cases.v, precision); actual != expected[precision+1] && !(math.IsNaN(actual) && math.IsNaN(expected[precision+1])) {
54-
t.Errorf("Round(%f, %d) %f != %f", cases.v, precision, actual, expected[precision+1])
56+
fmt.Println(cases.v, precision, actual, Round(0.5, precision))
57+
t.Errorf("Round(%v, %d) %f != %f", cases.v, precision, actual, expected[precision+1])
5558
}
5659
}
5760
}

0 commit comments

Comments
 (0)