floats/scalar: make use of math.Round and math.RoundToEven
MODIFY
floats/scalar/scalar.go
floats/scalar/scalar.go
@@ -123,11 +123,7 @@ func Round(x float64, prec int) float64 {
if math.IsInf(intermed, 0) {
return x
}
- if x < 0 {
- x = math.Ceil(intermed - 0.5)
- } else {
- x = math.Floor(intermed + 0.5)
- }
+ x = math.Round(intermed)
if x == 0 {
return 0
@@ -157,21 +153,7 @@ func RoundEven(x float64, prec int) float64 {
if math.IsInf(intermed, 0) {
return x
}
- if isHalfway(intermed) {
- correction, _ := math.Modf(math.Mod(intermed, 2))
- intermed += correction
- if intermed > 0 {
- x = math.Floor(intermed)
- } else {
- x = math.Ceil(intermed)
- }
- } else {
- if x < 0 {
- x = math.Ceil(intermed - 0.5)
- } else {
- x = math.Floor(intermed + 0.5)
- }
- }
+ x = math.RoundToEven(intermed)
if x == 0 {
return 0
@@ -180,12 +162,6 @@ func RoundEven(x float64, prec int) float64 {
return x / pow
}
-func isHalfway(x float64) bool {
- _, frac := math.Modf(x)
- frac = math.Abs(frac)
- return frac == 0.5 || (math.Nextafter(frac, math.Inf(-1)) < 0.5 && math.Nextafter(frac, math.Inf(1)) > 0.5)
-}
-
// Same returns true when the inputs have the same value, allowing NaN equality.
func Same(a, b float64) bool {
return a == b || (math.IsNaN(a) && math.IsNaN(b))

MODIFY
floats/scalar/scalar_test.go
floats/scalar/scalar_test.go
@@ -222,6 +222,8 @@ func TestRound(t *testing.T) {
{x: 123.4244999999999, prec: 3, want: 123.424},
{x: 123.4245, prec: 3, want: 123.425},
{x: 123.4245000000001, prec: 3, want: 123.425},
+ {x: -0.49999999999999994, prec: 0, want: 0},
+ {x: 0.49999999999999994, prec: 0, want: 0},
{x: 454.45, prec: 0, want: 454},
{x: 454.45, prec: 1, want: 454.5},
@@ -291,6 +293,8 @@ func TestRoundEven(t *testing.T) {
{x: 123.4244999999999, prec: 3, want: 123.424},
{x: 123.4245, prec: 3, want: 123.424},
{x: 123.4245000000001, prec: 3, want: 123.425},
+ {x: -0.49999999999999994, prec: 0, want: 0},
+ {x: 0.49999999999999994, prec: 0, want: 0},
{x: 454.45, prec: 0, want: 454},
{x: 454.45, prec: 1, want: 454.4},

floats/scalar: make use of math.Round and math.RoundToEven