lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Completion_heads_engraver broken?


From: Michael Käppler
Subject: Re: [PATCH] Completion_heads_engraver broken?
Date: Thu, 26 Feb 2009 11:23:47 +0100
User-agent: Thunderbird 2.0.0.12 (X11/20071114)

Hi all,
I don't completely understand the way how Duration::Duration(Rational r, bool scale) converts a rational number into a note and dots, but it's clear that the Completion_heads issue with splitting up breve and longa notes was caused by the way << behaves when given a negative number as shift-amount. I've tested this and it works perfectly for me. I'm a little unsure if this approach works when k gets so low that the rightest non-zero bit is shifted out into the nirvana... But for this moment I can't imagine cases where this could happen.
Nevertheless, please test and critizize!

Michael
>From 7dc5a8bdef5b04931856eb380939595d4efc3d7e Mon Sep 17 00:00:00 2001
From: root <address@hidden>
Date: Thu, 26 Feb 2009 11:01:15 +0100
Subject: [PATCH] This fixes an endless loop in duration.cc:67 when 
Duration::Duration(Rational r, bool scale) is 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 zero instead of 
right-shifting bits. The fix introduces a new function shift_left() in misc.hh, 
which behaves different.

---
 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 af924bb..0b80b1c 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 e33d836..4954895 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 >> abs(shiftamount)); 
+  else return (value << shiftamount);
+}
+
 inline Real
 linear_interpolate (Real x, Real x1, Real x2, Real y1, Real y2)
 {
-- 
1.5.6


reply via email to

[Prev in Thread] Current Thread [Next in Thread]