Skip to content

Commit

Permalink
exmath.Round 精度为负数时结算精准度问题 (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
thinkeridea committed Jan 12, 2021
1 parent 23f0fa7 commit c5bec17
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 7 deletions.
15 changes: 13 additions & 2 deletions exmath/benchmark/round_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,19 @@ import (
)

func BenchmarkRound(b *testing.B) {
f := 0.15807659924030304
for i := 0; i < b.N; i++ {
_ = exmath.Round(f, 5)
_ = exmath.Round(169543.34596, 0)
}
}

func BenchmarkRoundDecimal(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = exmath.Round(0.15807659924030304, 5)
}
}

func BenchmarkRoundInteger(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = exmath.Round(169543.34596, -5)
}
}
8 changes: 8 additions & 0 deletions exmath/round.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ import (
// Round 四舍五入,ROUND_HALF_UP 模式实现
// 返回将 val 根据指定精度 precision(十进制小数点后数字的数目)进行四舍五入的结果。precision 也可以是负数或零。
func Round(val float64, precision int) float64 {
if precision == 0 {
return math.Round(val)
}

p := math.Pow10(precision)
if precision < 0 {
return math.Floor(val*p+0.5) * math.Pow10(-precision)
}

return math.Floor(val*p+0.5) / p
}
13 changes: 8 additions & 5 deletions exmath/round_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package exmath

import (
"fmt"
"math"
"testing"
)
Expand All @@ -27,11 +28,11 @@ func TestRound(t *testing.T) {

{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{1.390671161567e-309, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // denormal
{0.49999999999999994, 0, 1, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5}, // 0.5-epsilon
{0.49999999999999994, 0, 0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5}, // 0.5-epsilon
{0.5, 0, 1, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5},
{0.5000000000000001, 0, 1, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5}, // 0.5+epsilon
{-1.5, 0, -1, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5},
{-2.5, 0, -2, -2.5, -2.5, -2.5, -2.5, -2.5, -2.5, -2.5},
{-1.5, 0, -2, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5},
{-2.5, 0, -3, -2.5, -2.5, -2.5, -2.5, -2.5, -2.5, -2.5},
{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()},
{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)},
}
Expand All @@ -44,14 +45,16 @@ func TestRound(t *testing.T) {
{2251799813685249.5, 2251799813685249.5, 2251799813685250, 2251799813685250, 2251799813685200, 2251799813685000, 2251799813690000, 2251799813700000, 2251799814000000, 2251799810000000},
{2251799813685250.5, 2251799813685250.5, 2251799813685251, 2251799813685250, 2251799813685300, 2251799813685000, 2251799813690000, 2251799813700000, 2251799814000000, 2251799810000000},
{4503599627370495.5, 4503599627370495, 4503599627370496, 4503599627370500, 4503599627370500, 4503599627370000, 4503599627370000, 4503599627400000, 4503599627000000, 4503599630000000},
{4503599627370497, 4503599627370497, 4503599627370498, 4503599627370500, 4503599627370500, 4503599627370000, 4503599627370000, 4503599627400000, 4503599627000000, 4503599630000000},
{4503599627370497, 4503599627370497, 4503599627370497, 4503599627370500, 4503599627370500, 4503599627370000, 4503599627370000, 4503599627400000, 4503599627000000, 4503599630000000},
{169543.34596, 169543.3, 169543, 169540, 169500, 170000, 170000, 200000, 0, 0},
}

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

0 comments on commit c5bec17

Please sign in to comment.