Bump version to 4.1-6
[LibreOffice.git] / writerfilter / source / resourcemodel / Fraction.cxx
blob762b9afed8e66496542b195b1d23bcf3db71276c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <resourcemodel/Fraction.hxx>
22 namespace writerfilter {
23 namespace resourcemodel {
25 // Stein's binary GCD for non-negative integers
26 // https://en.wikipedia.org/wiki/Binary_GCD_algorithm
27 sal_uInt32 gcd(sal_uInt32 a, sal_uInt32 b)
29 if (a == 0 || b == 0)
30 return a | b;
32 sal_uInt32 nShift = 0;
33 while (((a | b) & 1) == 0)
35 a >>= 1;
36 b >>= 1;
37 ++nShift;
40 while ((a & 1) == 0)
41 a >>= 1;
45 while ((b & 1) == 0)
46 b >>= 1;
48 if (a < b)
50 b -= a;
52 else
54 sal_uInt32 nDiff = a - b;
55 a = b;
56 b = nDiff;
59 b >>= 1;
61 while (b != 0);
63 return a << nShift;
66 sal_uInt32 lcm(sal_Int32 a, sal_Int32 b)
68 return abs(a * b) / gcd(abs(a), abs(b));
71 Fraction::Fraction(sal_Int32 nNumerator, sal_Int32 nDenominator)
73 init(nNumerator, nDenominator);
76 Fraction::~Fraction()
80 void Fraction::init(sal_Int32 nNumerator, sal_Int32 nDenominator)
82 sal_uInt32 nGCD = gcd(abs(nNumerator), abs(nDenominator));
84 mnNumerator = nNumerator/ nGCD;
85 mnDenominator = nDenominator / nGCD;
88 void Fraction::assign(const Fraction & rFraction)
90 init(rFraction.mnNumerator, rFraction.mnDenominator);
93 Fraction Fraction::inverse() const
95 return Fraction(mnDenominator, mnNumerator);
98 Fraction Fraction::operator + (const Fraction & rFraction) const
100 sal_uInt32 nLCM = lcm(mnDenominator, rFraction.mnDenominator);
102 return Fraction(mnNumerator * nLCM / mnDenominator + rFraction.mnNumerator * nLCM / rFraction.mnDenominator, nLCM);
105 Fraction Fraction::operator - (const Fraction & rFraction) const
107 sal_uInt32 nLCM = lcm(mnDenominator, rFraction.mnDenominator);
109 return Fraction(mnNumerator * nLCM / mnDenominator - rFraction.mnNumerator * nLCM / rFraction.mnDenominator, nLCM);
112 Fraction Fraction::operator * (const Fraction & rFraction) const
114 return Fraction(mnNumerator * rFraction.mnNumerator, mnDenominator * rFraction.mnDenominator);
117 Fraction Fraction::operator / (const Fraction & rFraction) const
119 return *this * rFraction.inverse();
122 Fraction Fraction::operator = (const Fraction & rFraction)
124 assign(rFraction);
126 return *this;
129 Fraction::operator sal_Int32() const
131 return mnNumerator / mnDenominator;
134 Fraction::operator float() const
136 return static_cast<float>(mnNumerator) / static_cast<float>(mnDenominator);
141 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */