From 1c1b4428ca2e71b62c2c5ed3042e680dd1085926 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michael=20K=C3=A4ppler?= Date: Sat, 28 Feb 2009 10:20:38 +0100 Subject: [PATCH] This fixes an endless loop in duration.cc:67. The loop occurred when Duration::Duration(Rational r, bool scale) was called with r.num() >= 2 * r.den(), f.e. the duration of a longa: r.num = 2, r.den = 1. If k < 0, the left-shifting-operator << returns an undefined value instead of right-shifting bits. The fix introduces a new function shift_left() in misc.hh, which behaves different. (cherry picked from commit 2a2eb61cf2f92967a1c6d5d872db1c906b2c2e73) --- lily/duration.cc | 6 +++--- lily/include/misc.hh | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lily/duration.cc b/lily/duration.cc index af924bb4b1..0b80b1ce1f 100644 --- a/lily/duration.cc +++ b/lily/duration.cc @@ -53,16 +53,16 @@ Duration::Duration (Rational r, bool scale) int p = r.num (); int q = r.den (); int k = intlog2 (q) - intlog2 (p); - if ((p << k) < q) + if (shift_left(p, k) < q) k++; - assert ((p << k) >= q && (p << (k-1)) < q); + assert (shift_left(p, k) >= q && shift_left(p, (k-1)) < q); /* If we were to write out log (p/q) in base 2, then the position of the first non-zero bit (ie. k in our notation) would be the durlog and the number of consecutive 1s after that bit would be the number of dots */ - p = (p << k) - q; + p = shift_left(p, k) - q; dots_ = 0; while ((p *= 2) >= q) { diff --git a/lily/include/misc.hh b/lily/include/misc.hh index e33d836381..12392c0cac 100644 --- a/lily/include/misc.hh +++ b/lily/include/misc.hh @@ -28,6 +28,13 @@ sign (int i) else return 0; } +inline int +shift_left (int value, int shiftamount) +{ + if (shiftamount < 0) return (value >> -shiftamount); + else return (value << shiftamount); +} + inline Real linear_interpolate (Real x, Real x1, Real x2, Real y1, Real y2) { -- 2.39.5