return d - d%m
}
+// lessThanHalf reports whether x+x < y but avoids overflow,
+// assuming x and y are both positive (Duration is signed).
+func lessThanHalf(x, y Duration) bool {
+ return uint64(x)+uint64(x) < uint64(y)
+}
+
// Round returns the result of rounding d to the nearest multiple of m.
// The rounding behavior for halfway values is to round away from zero.
// If the result exceeds the maximum (or minimum)
r := d % m
if d < 0 {
r = -r
- if r+r < m {
+ if lessThanHalf(r, m) {
return d + r
}
if d1 := d - m + r; d1 < d {
}
return minDuration // overflow
}
- if r+r < m {
+ if lessThanHalf(r, m) {
return d - r
}
if d1 := d + m - r; d1 > d {
return t
}
_, r := div(t, d)
- if r+r < d {
+ if lessThanHalf(r, d) {
return t.Add(-r)
}
return t.Add(d - r)
{Date(-1, January, 1, 12, 15, 31, 5e8, UTC), 3},
{Date(2012, January, 1, 12, 15, 30, 5e8, UTC), Second},
{Date(2012, January, 1, 12, 15, 31, 5e8, UTC), Second},
+ {Unix(-19012425939, 649146258), 7435029458905025217}, // 5.8*d rounds to 6*d, but .8*d+.8*d < 0 < d
}
func TestTruncateRound(t *testing.T) {
{9e18, 5e18, 1<<63 - 1},
{-8e18, 3e18, -9e18},
{-9e18, 5e18, -1 << 63},
+ {3<<61 - 1, 3 << 61, 3 << 61},
}
func TestDurationRound(t *testing.T) {