diff --git a/api/next/76821.txt b/api/next/76821.txt new file mode 100644 index 00000000000000..481fbb44b714b5 --- /dev/null +++ b/api/next/76821.txt @@ -0,0 +1,2 @@ +pkg math/big, method (*Rat) Floor() *Int #76821 +pkg math/big, method (*Rat) Ceil() *Int #76821 diff --git a/doc/next/6-stdlib/99-minor/math/big/76821.md b/doc/next/6-stdlib/99-minor/math/big/76821.md new file mode 100644 index 00000000000000..91e11ab1a94e28 --- /dev/null +++ b/doc/next/6-stdlib/99-minor/math/big/76821.md @@ -0,0 +1,2 @@ + +[Rat] now has [Rat.Floor] and [Rat.Ceil] methods. diff --git a/src/math/big/rat.go b/src/math/big/rat.go index c7f79a56661b12..1a8e2a6f591d11 100644 --- a/src/math/big/rat.go +++ b/src/math/big/rat.go @@ -559,3 +559,18 @@ func (z *Rat) Quo(x, y *Rat) *Rat { z.a.neg = a.neg != b.neg return z.norm() } + +// Floor returns the largest [Int] <= z. +func (z *Rat) Floor() *Int { + // z.b is positive, so Euclidean division == floor division + return new(Int).Div(&z.a, &z.b) +} + +// Ceil returns the smallest [Int] >= z. +func (z *Rat) Ceil() *Int { + if z.IsInt() { + return new(Int).Set(&z.a) + } + f := z.Floor() + return f.Add(f, intOne) +} diff --git a/src/math/big/rat_test.go b/src/math/big/rat_test.go index d98c89b3578a7a..3883bd3bd6cf57 100644 --- a/src/math/big/rat_test.go +++ b/src/math/big/rat_test.go @@ -744,3 +744,51 @@ func TestDenomRace(t *testing.T) { <-c } } + +func TestRatFloor(t *testing.T) { + var tests = []struct { + rat string + out int64 + }{ + {"123456.78", 123456}, + {"100.5", 100}, + {"5645.0222", 5645}, + {"89898989", 89898989}, + {"0", 0}, + {"-123456.78", -123457}, + {"-100.5", -101}, + {"-5645.0222", -5646}, + {"-89898989", -89898989}, + } + for i, test := range tests { + x, _ := new(Rat).SetString(test.rat) + out := x.Floor() + if out.Cmp(NewInt(test.out)) != 0 { + t.Errorf("#%d got out = %v; want %v", i, out, test.out) + } + } +} + +func TestRatCeil(t *testing.T) { + var tests = []struct { + rat string + out int64 + }{ + {"123456.78", 123457}, + {"100.5", 101}, + {"5645.0222", 5646}, + {"89898989", 89898989}, + {"0", 0}, + {"-123456.78", -123456}, + {"-100.5", -100}, + {"-5645.0222", -5645}, + {"-89898989", -89898989}, + } + for i, test := range tests { + x, _ := new(Rat).SetString(test.rat) + out := x.Ceil() + if out.Cmp(NewInt(test.out)) != 0 { + t.Errorf("#%d got out = %v; want %v", i, out, test.out) + } + } +}