1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include <resourcemodel/Fraction.hxx>
25
26 namespace writerfilter {
27 namespace resourcemodel {
28
gcd(sal_uInt32 a,sal_uInt32 b)29 sal_uInt32 gcd(sal_uInt32 a, sal_uInt32 b)
30 {
31 if (a == 0 || b == 0)
32 return a | b;
33
34 sal_uInt32 nShift = 0;
35 while (((a | b) & 1) == 0)
36 {
37 a >>= 1;
38 b >>= 1;
39 ++nShift;
40 }
41
42 while ((a & 1) == 0)
43 a >>= 1;
44
45 do
46 {
47 while ((b & 1) == 0)
48 b >>= 1;
49
50 if (a < b)
51 {
52 b -= a;
53 }
54 else
55 {
56 sal_uInt32 nDiff = a - b;
57 a = b;
58 b = nDiff;
59 }
60
61 b >>= 1;
62 }
63 while (b != 0);
64
65 return a << nShift;
66 }
67
lcm(sal_Int32 a,sal_Int32 b)68 sal_uInt32 lcm(sal_Int32 a, sal_Int32 b)
69 {
70 return abs(a * b) / gcd(abs(a), abs(b));
71 }
72
Fraction(sal_Int32 nNumerator,sal_Int32 nDenominator)73 Fraction::Fraction(sal_Int32 nNumerator, sal_Int32 nDenominator)
74 {
75 init(nNumerator, nDenominator);
76 }
77
Fraction(const Fraction & a,const Fraction & b)78 Fraction::Fraction(const Fraction & a, const Fraction & b)
79 {
80 init(a.mnNumerator * b.mnDenominator, a.mnDenominator * b.mnNumerator);
81 }
82
~Fraction()83 Fraction::~Fraction()
84 {
85 }
86
init(sal_Int32 nNumerator,sal_Int32 nDenominator)87 void Fraction::init(sal_Int32 nNumerator, sal_Int32 nDenominator)
88 {
89 sal_uInt32 nGCD = gcd(nNumerator, nDenominator);
90
91 mnNumerator = nNumerator/ nGCD;
92 mnDenominator = nDenominator / nGCD;
93 }
94
assign(const Fraction & rFraction)95 void Fraction::assign(const Fraction & rFraction)
96 {
97 init(rFraction.mnNumerator, rFraction.mnDenominator);
98 }
99
inverse() const100 Fraction Fraction::inverse() const
101 {
102 return Fraction(mnDenominator, mnNumerator);
103 }
104
operator +(const Fraction & rFraction) const105 Fraction Fraction::operator + (const Fraction & rFraction) const
106 {
107 sal_uInt32 nLCM = lcm(mnDenominator, rFraction.mnDenominator);
108
109 return Fraction(mnNumerator * nLCM / mnDenominator + rFraction.mnNumerator * nLCM / rFraction.mnDenominator, nLCM);
110 }
111
operator -(const Fraction & rFraction) const112 Fraction Fraction::operator - (const Fraction & rFraction) const
113 {
114 sal_uInt32 nLCM = lcm(mnDenominator, rFraction.mnDenominator);
115
116 return Fraction(mnNumerator * nLCM / mnDenominator - rFraction.mnNumerator * nLCM / rFraction.mnDenominator, nLCM);
117 }
118
operator *(const Fraction & rFraction) const119 Fraction Fraction::operator * (const Fraction & rFraction) const
120 {
121 return Fraction(mnNumerator * rFraction.mnNumerator, mnDenominator * rFraction.mnDenominator);
122 }
123
operator /(const Fraction & rFraction) const124 Fraction Fraction::operator / (const Fraction & rFraction) const
125 {
126 return *this * rFraction.inverse();
127 }
128
operator =(const Fraction & rFraction)129 Fraction Fraction::operator = (const Fraction & rFraction)
130 {
131 assign(rFraction);
132
133 return *this;
134 }
135
operator sal_Int32() const136 Fraction::operator sal_Int32() const
137 {
138 return mnNumerator / mnDenominator;
139 }
140
141 Fraction::operator float() const
142 {
143 return static_cast<float>(mnNumerator) / static_cast<float>(mnDenominator);
144 }
145
146 }}
147