Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add math constants corresbonding to util/math_constants.h for FixedPoint #1607

Merged
merged 2 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 78 additions & 4 deletions libopenage/util/fixed_point.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ constexpr static


/**
* Helper function that performs either a safe shift-right (amount > 0),
* or a safe shift-left (amount < 0).
* Helper function that performs either a safe shift-right (amount < 0),
* or a safe shift-left (amount >= 0).
*/
template <int amount, typename T>
constexpr static
Expand Down Expand Up @@ -169,6 +169,74 @@ class FixedPoint {
return FixedPoint::from_int(0);
}

/**
* Math constants represented in FixedPoint
*/
// naming, definition and value are kept compatible with `math_constants.h`
static constexpr FixedPoint e() {
return from_fixedpoint(FixedPoint<int64_t, 61>::from_raw_value(6267931151224907085ll));
}

static constexpr FixedPoint log2e() {
return from_fixedpoint(FixedPoint<int64_t, 61>::from_raw_value(3326628274461080622ll));
}

static constexpr FixedPoint log10e() {
return from_fixedpoint(FixedPoint<int64_t, 61>::from_raw_value(1001414895036696345ll));
}

static constexpr FixedPoint ln2() {
return from_fixedpoint(FixedPoint<int64_t, 61>::from_raw_value(1598288580650331957ll));
}

static constexpr FixedPoint ln10() {
return from_fixedpoint(FixedPoint<int64_t, 61>::from_raw_value(5309399739799983627ll));
}

static constexpr FixedPoint pi() {
return from_fixedpoint(FixedPoint<int64_t, 61>::from_raw_value(7244019458077122842ll));
}

static constexpr FixedPoint pi_2() {
return from_fixedpoint(FixedPoint<int64_t, 61>::from_raw_value(3622009729038561421ll));
}

static constexpr FixedPoint pi_4() {
return from_fixedpoint(FixedPoint<int64_t, 61>::from_raw_value(1811004864519280710ll));
}

static constexpr FixedPoint inv_pi() {
return from_fixedpoint(FixedPoint<int64_t, 61>::from_raw_value(733972625820500306ll));
}

static constexpr FixedPoint inv2_pi() {
return from_fixedpoint(FixedPoint<int64_t, 61>::from_raw_value(1467945251641000613ll));
}

static constexpr FixedPoint inv2_sqrt_pi() {
return from_fixedpoint(FixedPoint<int64_t, 61>::from_raw_value(2601865214189558307ll));
}

static constexpr FixedPoint tau() {
return from_fixedpoint(FixedPoint<int64_t, 60>::from_raw_value(7244019458077122842ll));
}

static constexpr FixedPoint degs_per_rad() {
return from_fixedpoint(FixedPoint<int64_t, 61>::from_raw_value(40244552544872904ll));
}

static constexpr FixedPoint rads_per_deg() {
return from_fixedpoint(FixedPoint<int64_t, 57>::from_raw_value(8257192040480628449ll));
}

static constexpr FixedPoint sqrt_2() {
return from_fixedpoint(FixedPoint<int64_t, 61>::from_raw_value(3260954456333195553ll));
}

static constexpr FixedPoint inv_sqrt_2() {
return from_fixedpoint(FixedPoint<int64_t, 61>::from_raw_value(1630477228166597776ll));
}

/**
* Factory function to get a fixed-point number from an integer.
*/
Expand All @@ -193,10 +261,16 @@ class FixedPoint {
/**
* Factory function to get a fixed-point number from a fixed-point number of different type.
*/
template <typename other_int_type, unsigned int other_fractional_bits>
template <typename other_int_type, unsigned int other_fractional_bits, typename std::enable_if<(fractional_bits > other_fractional_bits)>::type* = nullptr>
static constexpr FixedPoint from_fixedpoint(const FixedPoint<other_int_type, other_fractional_bits> &other) {
return FixedPoint::from_raw_value(
safe_shift<fractional_bits - other_fractional_bits, int_type>(static_cast<int_type>(other.get_raw_value())));
}

template <typename other_int_type, unsigned int other_fractional_bits, typename std::enable_if<(fractional_bits <= other_fractional_bits)>::type* = nullptr>
static constexpr FixedPoint from_fixedpoint(const FixedPoint<other_int_type, other_fractional_bits> &other) {
return FixedPoint::from_raw_value(
safe_shift<fractional_bits - other_fractional_bits, int_type>(other.get_raw_value()));
static_cast<int_type>(other.get_raw_value() / safe_shiftleft<other_fractional_bits - fractional_bits, other_int_type>(1)));
}

/**
Expand Down
24 changes: 24 additions & 0 deletions libopenage/util/fixed_point_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "../testing/testing.h"
#include "stringformatter.h"
#include "math_constants.h"

namespace openage {
namespace util {
Expand Down Expand Up @@ -98,6 +99,29 @@ void fixed_point() {
std::stringstream sstr("1234.5678");
sstr >> e;
TESTEQUALS_FLOAT(e.to_double(), 1234.5678, 1e-7);

TESTEQUALS_FLOAT(TestType::e().to_double(), math::E, 1e-7);
TESTEQUALS_FLOAT(TestType::log2e().to_double(), math::LOG2E, 1e-7);
TESTEQUALS_FLOAT(TestType::log10e().to_double(), math::LOG10E, 1e-7);
TESTEQUALS_FLOAT(TestType::ln2().to_double(), math::LN2, 1e-7);
TESTEQUALS_FLOAT(TestType::ln10().to_double(), math::LN10, 1e-7);
TESTEQUALS_FLOAT(TestType::pi().to_double(), math::PI, 1e-7);
TESTEQUALS_FLOAT(TestType::pi_2().to_double(), math::PI_2, 1e-7);
TESTEQUALS_FLOAT(TestType::pi_4().to_double(), math::PI_4, 1e-7);
TESTEQUALS_FLOAT(TestType::inv_pi().to_double(), math::INV_PI, 1e-7);
TESTEQUALS_FLOAT(TestType::inv2_pi().to_double(), math::INV2_PI, 1e-7);
TESTEQUALS_FLOAT(TestType::inv2_sqrt_pi().to_double(), math::INV2_SQRT_PI, 1e-7);
TESTEQUALS_FLOAT(TestType::tau().to_double(), math::TAU, 1e-7);
TESTEQUALS_FLOAT(TestType::degs_per_rad().to_double(), math::DEGSPERRAD, 1e-7);
TESTEQUALS_FLOAT(TestType::rads_per_deg().to_double(), math::RADSPERDEG, 1e-7);
TESTEQUALS_FLOAT(TestType::sqrt_2().to_double(), math::SQRT_2, 1e-7);
TESTEQUALS_FLOAT(TestType::inv_sqrt_2().to_double(), math::INV_SQRT_2, 1e-7);


using TestTypeShort = FixedPoint<int32_t, 16>;
TESTEQUALS_FLOAT(TestTypeShort::e().to_double(), math::E, 1e-3);
TESTEQUALS_FLOAT(TestTypeShort::pi().to_double(), math::PI, 1e-3);

}

}}} // openage::util::tests
Loading