summaryrefslogtreecommitdiffstats
path: root/pokemod/Frac.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'pokemod/Frac.cpp')
-rw-r--r--pokemod/Frac.cpp172
1 files changed, 172 insertions, 0 deletions
diff --git a/pokemod/Frac.cpp b/pokemod/Frac.cpp
new file mode 100644
index 00000000..7a3ddbb1
--- /dev/null
+++ b/pokemod/Frac.cpp
@@ -0,0 +1,172 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name: Frac.cpp
+// Purpose: A class to make handling fractions easier
+// Author: Ben Boeckel
+// Modified by: Ben Boeckel
+// Created: Sun Mar 18 15:25:16 2007
+// Copyright: ©2007 Ben Boeckel and Nerdy Productions
+// Licence:
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+/////////////////////////////////////////////////////////////////////////////
+
+#include "Frac.h"
+
+PokeMod::Frac::Frac(bool i)
+{
+ Log("Frac: Initializing", PM_DEBUG_DEBUG);
+ num = 1;
+ denom = 1;
+ improper = i;
+}
+
+PokeMod::Frac::Frac(unsigned n, unsigned d, bool i)
+{
+ Log(String("Frac: Initializing as %u/%u (%u)", n, d, i), PM_DEBUG_DEBUG);
+ Set(n, d, i);
+}
+
+void PokeMod::Frac::ImportXml(XmlElement &xml)
+{
+ LogImportStart("Frac");
+ String curName;
+ num = 1;
+ denom = 1;
+ improper = false;
+ Reduce();
+ xml.ClearCounter();
+ for (XmlElement *child = xml.NextElement(); child; child = xml.NextElement())
+ {
+ curName = child->GetName();
+ if (curName == "num")
+ child->GetValue(num, 1);
+ else if (curName == "denom")
+ child->GetValue(denom, 1);
+ else if (curName == "improper")
+ child->GetValue(improper, false);
+ else
+ LogUnknownXml("Frac", curName);
+ }
+ Log(String("Frac Import: Imported %u/%u", num, denom), PM_DEBUG_INFO);
+}
+
+PokeMod::XmlElement PokeMod::Frac::ExportXml(const String &val)
+{
+ Log(String("Frac Export: Starting %u/%u as %s", num, denom, val.c_str()), PM_DEBUG_INFO);
+ // Reduce fraction before storing
+ Reduce();
+ // Declare the elements
+ XmlElement exFrac(val, 0, true);
+ exFrac.AddElement("num", num);
+ exFrac.AddElement("denom", denom);
+ exFrac.AddElement("improper", improper);
+ Log(String("Frac Export: Finished %u/%u as %s", num, denom, val.c_str()), PM_DEBUG_INFO);
+ return exFrac;
+}
+
+void PokeMod::Frac::Set(unsigned n, unsigned d)
+{
+ Log(String("Frac: Setting to %u/%u", n, d), PM_DEBUG_DEBUG);
+ SetDenom(d);
+ SetNum(n);
+ Reduce();
+}
+
+void PokeMod::Frac::Set(unsigned n, unsigned d, bool i)
+{
+ SetImproper(i);
+ Set(n, d);
+}
+
+void PokeMod::Frac::SetNum(unsigned n)
+{
+ // Make sure the numerator is less than the denominator if proper
+ if ((n <= denom) || improper)
+ {
+ Log(String("Frac: Setting numerator to %u (%u/%u)", n, n, denom), PM_DEBUG_DEBUG);
+ num = n;
+ }
+ else
+ Log(String("Frac: Setting tried to set numerator to %u when denominator is %u", n, denom), PM_DEBUG_DEBUG);
+}
+
+void PokeMod::Frac::SetDenom(unsigned d)
+{
+ // Make sure the denominator isn't 0
+ if (d)
+ {
+ Log(String("Frac: Setting denominator to %u", d), PM_DEBUG_DEBUG);
+ denom = d;
+ }
+ else
+ Log("Frac: Attempting to set denominator to 0", PM_DEBUG_DEBUG);
+ // Set the numerator to less than the denominator if proper
+ if ((num <= denom) && !improper)
+ {
+ Log(String("Frac: Setting numerator to 1 after denominator reset to (%u)", d), PM_DEBUG_DEBUG);
+ num = denom % num;
+ }
+}
+
+void PokeMod::Frac::SetImproper(bool i)
+{
+ Log(String("Frac: Setting as %s", i ? "improper" : "proper"), PM_DEBUG_DEBUG);
+ improper = i;
+ Set(num, denom);
+}
+
+unsigned PokeMod::Frac::GetNum()
+{
+ Log(String("Frac: Fetching the numerator (%u)", num), PM_DEBUG_DEBUG);
+ return num;
+}
+
+unsigned PokeMod::Frac::GetDenom()
+{
+ Log(String("Frac: Fetching the denominator (%u)", denom), PM_DEBUG_DEBUG);
+ return denom;
+}
+
+bool PokeMod::Frac::GetImproper()
+{
+ Log(String("Frac: Fetching improper (%u)", improper), PM_DEBUG_DEBUG);
+ return improper;
+}
+
+float PokeMod::Frac::GetValue()
+{
+ Log(String("Frac: Fetching the value (%f)", num / denom), PM_DEBUG_DEBUG);
+ return (num / denom);
+}
+
+PokeMod::Frac::operator float()
+{
+ return GetValue();
+}
+
+void PokeMod::Frac::Reduce()
+{
+ Log(String("Frac: Reducing %u/%u", num, denom), PM_DEBUG_DEBUG);
+ // Iterate until i is greater than the square root on num
+ for (unsigned i = 2; i * i <= num; ++i)
+ {
+ // Keep iterating while i is a factor of both
+ while (!((num % i) || (denom % i)))
+ {
+ num /= i;
+ denom /= i;
+ }
+ }
+ Log(String("Frac: Reduced to %u/%u", num, denom), PM_DEBUG_DEBUG);
+}