temporal: fix implementation of Beats::snap_to(), and add variants

::snap_to() was intended to round a Beats value to the nearest multiple
of another Beats value. It did not do that, but instead rounded down.
Worse, it used Beats::operator/ which in turn uses int_div_round(),
which is incorrect for a situation where we need integer truncation.

The changes fix the actual arithmetic and add 2 variant functions so that the
API includes round down, round up and round to nearest.
This commit is contained in:
Paul Davis 2021-11-29 21:44:20 -07:00
parent 83c7ac4f38
commit 940d8844e3

View File

@ -158,8 +158,15 @@ public:
return *this;
}
Beats snap_to (Temporal::Beats const & snap) const {
return (*this / snap) * snap;
public:
Beats round_up_to_multiple (Beats const & multiple) const {
return ticks (((to_ticks() + (multiple.to_ticks() - 1)) / multiple.to_ticks()) * multiple.to_ticks());
}
Beats round_to_multiple (Beats const & multiple) const {
return ticks (((to_ticks() + (int_div_round (multiple.to_ticks(), (int64_t) 2))) / multiple.to_ticks()) * multiple.to_ticks());
}
Beats round_down_to_multiple (Beats const & multiple) const {
return ticks ((to_ticks() / multiple.to_ticks()) * multiple.to_ticks());
}
Beats round_to_beat() const {