commit 79570512f6fee99debf38862aa75a6211634272d
parent c0934431e09444b95d415e89bd48540916c77ad4
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date: Tue, 27 Nov 2018 18:32:08 +0000
fraction type
Diffstat:
2 files changed, 138 insertions(+), 0 deletions(-)
diff --git a/include/kfr/base/fraction.hpp b/include/kfr/base/fraction.hpp
@@ -0,0 +1,136 @@
+/** @addtogroup types
+ * @{
+ */
+/*
+ Copyright (C) 2016 D Levin (https://www.kfrlib.com)
+ This file is part of KFR
+
+ KFR 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 3 of the License, or
+ (at your option) any later version.
+
+ KFR 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 KFR.
+
+ If GPL is not suitable for your project, you must purchase a commercial license to use KFR.
+ Buying a commercial license is mandatory as soon as you develop commercial activities without
+ disclosing the source code of your own applications.
+ See https://www.kfrlib.com for details.
+ */
+#pragma once
+
+#include "operators.hpp"
+#include "vec.hpp"
+
+namespace kfr
+{
+
+struct fraction
+{
+ fraction(i64 num = 0, i64 den = 1) : numerator(num), denominator(den) { normalize(); }
+ void normalize()
+ {
+ if (denominator < 0)
+ {
+ denominator = -denominator;
+ numerator = -numerator;
+ }
+ const i64 z = gcd(std::abs(numerator), std::abs(denominator));
+ numerator /= z;
+ denominator /= z;
+ }
+
+ i64 numerator;
+ i64 denominator;
+
+ fraction operator+() const { return *this; }
+ fraction operator-() const { return fraction(-numerator, denominator); }
+
+ explicit operator bool() const { return numerator != 0; }
+ explicit operator double() const { return static_cast<double>(numerator) / denominator; }
+ explicit operator float() const { return static_cast<float>(numerator) / denominator; }
+ explicit operator i64() const { return static_cast<i64>(numerator) / denominator; }
+
+ friend fraction operator+(const fraction& x, const fraction& y)
+ {
+ return fraction(x.numerator * y.denominator + y.numerator * x.denominator,
+ x.denominator * y.denominator);
+ }
+ friend fraction operator-(const fraction& x, const fraction& y)
+ {
+ return fraction(x.numerator * y.denominator - y.numerator * x.denominator,
+ x.denominator * y.denominator);
+ }
+ friend fraction operator*(const fraction& x, const fraction& y)
+ {
+ return fraction(x.numerator * y.numerator, x.denominator * y.denominator);
+ }
+ friend fraction operator/(const fraction& x, const fraction& y)
+ {
+ return fraction(x.numerator * y.denominator, x.denominator * y.numerator);
+ }
+
+ friend bool operator==(const fraction& x, const fraction& y)
+ {
+ return x.numerator == y.numerator && x.denominator == y.denominator;
+ }
+ friend bool operator!=(const fraction& x, const fraction& y) { return !(operator==(x, y)); }
+ friend bool operator<(const fraction& x, const fraction& y)
+ {
+ return x.numerator * y.denominator < y.numerator * x.denominator;
+ }
+ friend bool operator<=(const fraction& x, const fraction& y)
+ {
+ return x.numerator * y.denominator <= y.numerator * x.denominator;
+ }
+ friend bool operator>(const fraction& x, const fraction& y)
+ {
+ return x.numerator * y.denominator > y.numerator * x.denominator;
+ }
+ friend bool operator>=(const fraction& x, const fraction& y)
+ {
+ return x.numerator * y.denominator >= y.numerator * x.denominator;
+ }
+
+ fraction& operator+=(const fraction& y)
+ {
+ *this = *this + y;
+ return *this;
+ }
+ fraction& operator-=(const fraction& y)
+ {
+ *this = *this - y;
+ return *this;
+ }
+ fraction& operator*=(const fraction& y)
+ {
+ *this = *this * y;
+ return *this;
+ }
+ fraction& operator/=(const fraction& y)
+ {
+ *this = *this / y;
+ return *this;
+ }
+
+private:
+ static i64 gcd(i64 a, i64 b)
+ {
+ i64 r;
+ while (b > 0)
+ {
+ r = a % b;
+ a = b;
+ b = r;
+ }
+ return a;
+ }
+ static i64 lcm(i64 a, i64 b) { return std::abs(a * b) / gcd(a, b); }
+};
+} // namespace kfr
diff --git a/sources.cmake b/sources.cmake
@@ -27,6 +27,7 @@ set(
${PROJECT_SOURCE_DIR}/include/kfr/base/digitreverse.hpp
${PROJECT_SOURCE_DIR}/include/kfr/base/expression.hpp
${PROJECT_SOURCE_DIR}/include/kfr/base/filter.hpp
+ ${PROJECT_SOURCE_DIR}/include/kfr/base/fraction.hpp
${PROJECT_SOURCE_DIR}/include/kfr/base/function.hpp
${PROJECT_SOURCE_DIR}/include/kfr/base/gamma.hpp
${PROJECT_SOURCE_DIR}/include/kfr/base/generators.hpp
@@ -96,6 +97,7 @@ set(
${PROJECT_SOURCE_DIR}/include/kfr/dft/fft.hpp
${PROJECT_SOURCE_DIR}/include/kfr/dft/ft.hpp
${PROJECT_SOURCE_DIR}/include/kfr/dft/reference_dft.hpp
+ ${PROJECT_SOURCE_DIR}/include/kfr/dft/dft_c.h
${PROJECT_SOURCE_DIR}/include/kfr/dsp/biquad.hpp
${PROJECT_SOURCE_DIR}/include/kfr/dsp/biquad_design.hpp
${PROJECT_SOURCE_DIR}/include/kfr/dsp/dcremove.hpp