这是indexloc提供的服务,不要输入任何密码
Skip to content
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