Remove redundant acknowledger in Bar_number_engraver.
[lilypond/mpolesky.git] / flower / rational.cc
blob048d45fcbe112b9f3d66f3853abc58bea6dec747
1 /*
2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 1997--2010 Han-Wen Nienhuys <hanwen@xs4all.nl>
6 LilyPond is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 LilyPond is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
20 #include "rational.hh"
22 #include <cmath>
23 #include <cassert>
24 #include <cstdlib>
25 using namespace std;
27 #include "string-convert.hh"
28 #include "libc-extension.hh"
30 double
31 Rational::to_double () const
33 if (sign_ == -1 || sign_ == 1 || sign_ == 0)
34 return ((double)sign_) * num_ / den_;
35 if (sign_ == -2)
36 return -HUGE_VAL;
37 else if (sign_ == 2)
38 return HUGE_VAL;
39 else
40 assert (false);
42 return 0.0;
46 #ifdef STREAM_SUPPORT
47 ostream &
48 operator << (ostream &o, Rational r)
50 o << r.string ();
51 return o;
53 #endif
55 Rational
56 Rational::abs () const
58 return Rational (num_, den_);
61 Rational
62 Rational::trunc_rat () const
64 if (is_infinity())
65 return *this;
66 return Rational ((num_ - (num_ % den_)) * sign_, den_);
69 Rational::Rational ()
71 sign_ = 0;
72 num_ = den_ = 1;
75 Rational::Rational (I64 n, I64 d)
77 sign_ = ::sign (n) * ::sign (d);
78 num_ = ::abs (n);
79 den_ = ::abs (d);
80 normalize ();
83 Rational::Rational (I64 n)
85 sign_ = ::sign (n);
86 num_ = ::abs (n);
87 den_ = 1;
90 Rational::Rational (U64 n)
92 sign_ = 1;
93 num_ = n;
94 den_ = 1;
97 Rational::Rational (int n)
99 sign_ = ::sign (n);
100 num_ = ::abs (n);
101 den_ = 1;
105 void
106 Rational::set_infinite (int s)
108 sign_ = ::sign (s) * 2;
109 num_ = 1;
112 Rational
113 Rational::operator - () const
115 Rational r (*this);
116 r.negate ();
117 return r;
120 Rational
121 Rational::div_rat (Rational div) const
123 Rational r (*this);
124 r /= div;
125 return r.trunc_rat ();
128 Rational
129 Rational::mod_rat (Rational div) const
131 Rational r (*this);
132 r = (r / div - r.div_rat (div)) * div;
133 return r;
138 copy & paste from scm_gcd (GUILE).
140 static I64
141 gcd (I64 u, I64 v)
143 I64 result = 0;
144 if (u == 0)
145 result = v;
146 else if (v == 0)
147 result = u;
148 else
150 I64 k = 1;
151 I64 t;
152 /* Determine a common factor 2^k */
153 while (!(1 & (u | v)))
155 k <<= 1;
156 u >>= 1;
157 v >>= 1;
159 /* Now, any factor 2^n can be eliminated */
160 if (u & 1)
161 t = -v;
162 else
164 t = u;
166 t = t >> 1;
168 if (!(1 & t))
169 goto b3;
170 if (t > 0)
171 u = t;
172 else
173 v = -t;
174 t = u - v;
175 if (t != 0)
176 goto b3;
177 result = u * k;
180 return result;
184 void
185 Rational::normalize ()
187 if (!sign_)
189 den_ = 1;
190 num_ = 0;
192 else if (!den_)
194 sign_ = 2;
195 num_ = 1;
197 else if (!num_)
199 sign_ = 0;
200 den_ = 1;
202 else
204 I64 g = gcd (num_, den_);
206 num_ /= g;
207 den_ /= g;
211 Rational::sign () const
213 return ::sign (sign_);
217 Rational::compare (Rational const &r, Rational const &s)
219 if (r.sign_ < s.sign_)
220 return -1;
221 else if (r.sign_ > s.sign_)
222 return 1;
223 else if (r.is_infinity ())
224 return 0;
225 else if (r.sign_ == 0)
226 return 0;
227 return r.sign_ * ::sign ((I64) (r.num_ * s.den_) - (I64) (s.num_ * r.den_));
231 compare (Rational const &r, Rational const &s)
233 return Rational::compare (r, s);
236 Rational &
237 Rational::operator %= (Rational r)
239 *this = mod_rat (r);
240 return *this;
243 Rational &
244 Rational::operator += (Rational r)
246 if (is_infinity ())
248 else if (r.is_infinity ())
249 *this = r;
250 else
252 I64 lcm = (den_ / gcd (r.den_, den_)) * r.den_;
253 I64 n = sign_ * num_ * (lcm / den_) + r.sign_ * r.num_ * (lcm / r.den_);
254 I64 d = lcm;
255 sign_ = ::sign (n) * ::sign (d);
256 num_ = ::abs (n);
257 den_ = ::abs (d);
258 normalize ();
260 return *this;
264 copied from libg++ 2.8.0
266 Rational::Rational (double x)
268 if (x != 0.0)
270 sign_ = ::sign (x);
271 x *= sign_;
273 int expt;
274 double mantissa = frexp (x, &expt);
276 const int FACT = 1 << 20;
279 Thanks to Afie for this too simple idea.
281 do not blindly substitute by libg++ code, since that uses
282 arbitrary-size integers. The rationals would overflow too
283 easily.
286 num_ = (U64) (mantissa * FACT);
287 den_ = (U64) FACT;
288 normalize ();
289 if (expt < 0)
290 den_ <<= -expt;
291 else
292 num_ <<= expt;
293 normalize ();
295 else
297 num_ = 0;
298 den_ = 1;
299 sign_ = 0;
300 normalize ();
304 void
305 Rational::invert ()
307 I64 r (num_);
308 num_ = den_;
309 den_ = r;
312 Rational &
313 Rational::operator *= (Rational r)
315 sign_ *= ::sign (r.sign_);
316 if (r.is_infinity ())
318 sign_ = sign () * 2;
319 goto exit_func;
322 num_ *= r.num_;
323 den_ *= r.den_;
325 normalize ();
326 exit_func:
327 return *this;
330 Rational &
331 Rational::operator /= (Rational r)
333 r.invert ();
334 return (*this *= r);
337 void
338 Rational::negate ()
340 sign_ *= -1;
343 Rational &
344 Rational::operator -= (Rational r)
346 r.negate ();
347 return (*this += r);
350 string
351 Rational::to_string () const
353 if (is_infinity ())
355 string s (sign_ > 0 ? "" : "-");
356 return string (s + "infinity");
359 string s = ::to_string (num ());
360 if (den () != 1 && num ())
361 s += "/" + ::to_string (den ());
362 return s;
366 Rational::to_int () const
368 return (int) num () / den ();
372 sign (Rational r)
374 return r.sign ();
377 bool
378 Rational::is_infinity () const
380 return sign_ == 2 || sign_ == -2;