]> git.donarmstrong.com Git - lilypond.git/commitdiff
This fixes an endless loop in duration.cc:67.
authorMichael Käppler <xmichael-k@web.de>
Sat, 28 Feb 2009 09:20:38 +0000 (10:20 +0100)
committerPatrick McCarty <pnorcks@gmail.com>
Fri, 17 Jul 2009 07:36:00 +0000 (00:36 -0700)
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
lily/include/misc.hh

index af924bb4b17036df70c28d8ce7583c945002ddbe..0b80b1ce1f33dba7ed7ec97910edfdd33913e5b7 100644 (file)
@@ -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)
        {
index e33d8363819a658267d0e15e62868fb1fe29e631..12392c0cacd804dcee2db84c0e0aaec93ef0651a 100644 (file)
@@ -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)
 {