finish fixed point
parent
27af4e339f
commit
26d215be0a
|
@ -1,7 +1,7 @@
|
|||
cmake_minimum_required(VERSION 3.5)
|
||||
include(cmake/color.cmake)
|
||||
|
||||
set(BLT_VERSION 0.16.4)
|
||||
set(BLT_VERSION 0.16.5)
|
||||
set(BLT_TEST_VERSION 0.0.1)
|
||||
|
||||
set(BLT_TARGET BLT)
|
||||
|
|
|
@ -20,140 +20,232 @@
|
|||
#define BLT_FIXED_POINT_H
|
||||
|
||||
#include <blt/std/types.h>
|
||||
#include <blt/std/utility.h>
|
||||
//#include <blt/std/utility.h>
|
||||
|
||||
#define BLT_DEBUG_NO_INLINE BLT_ATTRIB_NO_INLINE
|
||||
//#define BLT_DEBUG_NO_INLINE BLT_ATTRIB_NO_INLINE
|
||||
#define BLT_DEBUG_NO_INLINE
|
||||
|
||||
namespace blt
|
||||
{
|
||||
struct fp64
|
||||
{
|
||||
private:
|
||||
u64 v = 0;
|
||||
i64 v = 0;
|
||||
|
||||
fp64() = default;
|
||||
|
||||
explicit fp64(u64 v): v(v)
|
||||
{}
|
||||
|
||||
constexpr fp64() = default;
|
||||
public:
|
||||
static fp64 from_u64(u64 ui)
|
||||
constexpr explicit fp64(u64 ui): v(from_u64(ui))
|
||||
{}
|
||||
|
||||
constexpr explicit fp64(i64 si): v(from_i64(si))
|
||||
{}
|
||||
|
||||
constexpr explicit fp64(u32 ui): v(from_u32(ui))
|
||||
{}
|
||||
|
||||
constexpr explicit fp64(i32 si): v(from_i32(si))
|
||||
{}
|
||||
|
||||
constexpr explicit fp64(f32 f): v(from_f32(f))
|
||||
{}
|
||||
|
||||
constexpr explicit fp64(f64 d): v(from_f64(d))
|
||||
{}
|
||||
|
||||
constexpr static inline fp64 from_raw(i64 i)
|
||||
{
|
||||
fp64 r;
|
||||
r.v = i;
|
||||
return r;
|
||||
}
|
||||
|
||||
constexpr static inline fp64 from_raw_u64(u64 u)
|
||||
{
|
||||
fp64 r;
|
||||
r.v = static_cast<i64>(u);
|
||||
return r;
|
||||
}
|
||||
|
||||
constexpr static inline fp64 from_u64(u64 ui)
|
||||
{
|
||||
return from_i64(static_cast<i64>(ui));
|
||||
}
|
||||
|
||||
constexpr static inline fp64 from_i64(i64 si)
|
||||
{
|
||||
return from_raw(si << 32);
|
||||
}
|
||||
|
||||
constexpr static inline fp64 from_u32(u32 ui)
|
||||
{
|
||||
return from_i64(static_cast<i64>(ui));
|
||||
}
|
||||
|
||||
constexpr static inline fp64 from_i32(i32 si)
|
||||
{
|
||||
return from_i64(static_cast<i64>(si));
|
||||
}
|
||||
|
||||
constexpr static inline fp64 from_f64(f64 d)
|
||||
{
|
||||
fp64 fp;
|
||||
fp.v = ui << 32;
|
||||
fp.v = static_cast<i64>(d * (1ul << 32ul));
|
||||
return fp;
|
||||
}
|
||||
|
||||
static fp64 from_i64(i64 si)
|
||||
{
|
||||
u64 ui = static_cast<u64>(si);
|
||||
fp64 fp;
|
||||
fp.v = ui << 32;
|
||||
return fp;
|
||||
}
|
||||
|
||||
static fp64 from_f64(f64 d)
|
||||
{
|
||||
fp64 fp;
|
||||
fp.v = static_cast<u64>(d * (1ul << 32ul));
|
||||
return fp;
|
||||
}
|
||||
|
||||
static fp64 from_f32(f32 f)
|
||||
constexpr static inline fp64 from_f32(f32 f)
|
||||
{
|
||||
return from_f64(static_cast<double>(f));
|
||||
}
|
||||
|
||||
BLT_DEBUG_NO_INLINE friend fp64 operator+(fp64 left, fp64 right)
|
||||
BLT_DEBUG_NO_INLINE constexpr friend inline fp64 operator+(fp64 left, fp64 right)
|
||||
{
|
||||
return fp64(left.v + right.v);
|
||||
return from_raw(left.v + right.v);
|
||||
}
|
||||
|
||||
BLT_DEBUG_NO_INLINE friend fp64 operator-(fp64 left, fp64 right)
|
||||
BLT_DEBUG_NO_INLINE constexpr friend inline fp64 operator-(fp64 left, fp64 right)
|
||||
{
|
||||
return fp64(left.v - right.v);
|
||||
return from_raw(left.v - right.v);
|
||||
}
|
||||
|
||||
BLT_DEBUG_NO_INLINE friend fp64 operator*(fp64 left, fp64 right)
|
||||
BLT_DEBUG_NO_INLINE constexpr friend inline fp64 operator*(fp64 left, fp64 right)
|
||||
{
|
||||
auto lhs = static_cast<unsigned __int128>(left.v);
|
||||
auto rhs = static_cast<unsigned __int128>(right.v);
|
||||
return fp64(static_cast<u64>((lhs * rhs) >> 32));
|
||||
auto lhs = static_cast<__int128>(left.v);
|
||||
auto rhs = static_cast<__int128>(right.v);
|
||||
return from_raw(static_cast<i64>((lhs * rhs) >> 32));
|
||||
}
|
||||
|
||||
BLT_DEBUG_NO_INLINE friend fp64 operator/(fp64 left, fp64 right)
|
||||
BLT_DEBUG_NO_INLINE constexpr friend inline fp64 operator/(fp64 left, fp64 right)
|
||||
{
|
||||
auto lhs = static_cast<unsigned __int128>(left.v) << 32;
|
||||
auto rhs = static_cast<unsigned __int128>(right.v);
|
||||
|
||||
return fp64(static_cast<u64>(lhs / rhs));
|
||||
auto lhs = static_cast<__int128>(left.v) << 32;
|
||||
return from_raw(static_cast<i64>(lhs / right.v));
|
||||
}
|
||||
|
||||
[[nodiscard]] inline u64 as_u64() const
|
||||
BLT_DEBUG_NO_INLINE constexpr inline fp64& operator+=(fp64 add)
|
||||
{
|
||||
v += add.v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BLT_DEBUG_NO_INLINE constexpr inline fp64& operator-=(fp64 sub)
|
||||
{
|
||||
v -= sub.v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BLT_DEBUG_NO_INLINE constexpr inline fp64& operator*=(fp64 mul)
|
||||
{
|
||||
auto lhs = static_cast<__int128>(v);
|
||||
auto rhs = static_cast<__int128>(mul.v);
|
||||
v = static_cast<i64>((lhs * rhs) >> 32);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BLT_DEBUG_NO_INLINE constexpr inline fp64& operator/=(fp64 div)
|
||||
{
|
||||
auto lhs = static_cast<__int128>(v) << 32;
|
||||
v = static_cast<i64>(lhs / div.v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr inline u64 as_u64() const
|
||||
{
|
||||
return static_cast<u64>(v) >> 32;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr inline i64 as_i64() const
|
||||
{
|
||||
return v >> 32;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline i64 as_i64() const
|
||||
[[nodiscard]] constexpr inline u32 as_u32() const
|
||||
{
|
||||
return static_cast<i64>(as_u64());
|
||||
return static_cast<u32>(v >> 32);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline u32 as_u32() const
|
||||
[[nodiscard]] constexpr inline i32 as_i32() const
|
||||
{
|
||||
return static_cast<u32>(as_u64());
|
||||
return static_cast<i32>(v >> 32);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline i32 as_i32() const
|
||||
{
|
||||
return static_cast<i32>(as_u64());
|
||||
}
|
||||
|
||||
[[nodiscard]] inline f64 as_f64() const
|
||||
[[nodiscard]] constexpr inline f64 as_f64() const
|
||||
{
|
||||
return static_cast<f64>(v) / static_cast<f64>(1ul << 32ul);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline f32 as_f32() const
|
||||
[[nodiscard]] constexpr inline f32 as_f32() const
|
||||
{
|
||||
return static_cast<f32>(as_f64());
|
||||
return static_cast<f32>(v) / static_cast<f32>(1ul << 32ul);
|
||||
}
|
||||
|
||||
inline explicit operator u64() const
|
||||
constexpr inline explicit operator u64() const
|
||||
{
|
||||
return as_u64();
|
||||
}
|
||||
|
||||
inline explicit operator i64() const
|
||||
constexpr inline explicit operator i64() const
|
||||
{
|
||||
return as_i64();
|
||||
}
|
||||
|
||||
inline explicit operator u32() const
|
||||
constexpr inline explicit operator u32() const
|
||||
{
|
||||
return as_u32();
|
||||
}
|
||||
|
||||
inline explicit operator i32() const
|
||||
constexpr inline explicit operator i32() const
|
||||
{
|
||||
return as_i32();
|
||||
}
|
||||
|
||||
inline explicit operator f32() const
|
||||
constexpr inline explicit operator f32() const
|
||||
{
|
||||
return as_f32();
|
||||
};
|
||||
|
||||
inline explicit operator f64() const
|
||||
constexpr inline explicit operator f64() const
|
||||
{
|
||||
return as_f64();
|
||||
}
|
||||
|
||||
[[nodiscard]] u64 raw() const
|
||||
[[nodiscard]] constexpr u64 raw() const
|
||||
{
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
// max unsigned integer value
|
||||
static constexpr const inline fp64 FP64_UMAX = fp64::from_raw_u64(0xFFFFFFFF00000000);
|
||||
// min unsigned integer value
|
||||
static constexpr const inline fp64 FP64_UMIN = fp64::from_raw_u64(0x0000000000000000);
|
||||
// max signed integer value
|
||||
static constexpr const inline fp64 FP64_IMAX = fp64::from_raw_u64(0x7FFFFFFF00000000);
|
||||
// min signed integer value
|
||||
static constexpr const inline fp64 FP64_IMIN = fp64::from_raw_u64(0x8000000000000000);
|
||||
// max value storable including floating point
|
||||
static constexpr const inline fp64 FP64_FMAX = fp64::from_raw_u64(0x7FFFFFFFFFFFFFFF);
|
||||
// min float point number
|
||||
static constexpr const inline fp64 FP64_FMIN = fp64::from_raw_u64(0x8000000000000000);
|
||||
// smallest decimal number
|
||||
static constexpr const inline fp64 FP64_EPSILON = fp64::from_raw_u64(0x0000000000000001);
|
||||
// pi
|
||||
static constexpr const inline fp64 FP64_PI = fp64::from_f64(3.14159265358979323846);
|
||||
// pi / 2
|
||||
static constexpr const inline fp64 FP64_PI_2 = fp64::from_f64(1.57079632679489661923);
|
||||
// pi / 4
|
||||
static constexpr const inline fp64 FP64_PI_4 = fp64::from_f64(0.78539816339744830962);
|
||||
// 1 / pi
|
||||
static constexpr const inline fp64 FP64_1_PI = fp64::from_f64(0.31830988618379067154);
|
||||
// 2 / pi
|
||||
static constexpr const inline fp64 FP64_2_PI = fp64::from_f64(0.63661977236758134308);
|
||||
// sqrt(2)
|
||||
static constexpr const inline fp64 FP64_SQRT2 = fp64::from_f64(1.41421356237309504880);
|
||||
// 1 / sqrt(2)
|
||||
static constexpr const inline fp64 FP64_1_SQRT2 = fp64::from_f64(0.70710678118654752440);
|
||||
// e
|
||||
static constexpr const inline fp64 FP64_E = fp64::from_f64(2.7182818284590452354f);
|
||||
// log2(e)
|
||||
static constexpr const inline fp64 FP64_LOG2E = fp64::from_f64(1.4426950408889634074f);
|
||||
}
|
||||
|
||||
#endif //BLT_FIXED_POINT_H
|
||||
|
|
|
@ -19,31 +19,71 @@
|
|||
#include <blt/math/vectors.h>
|
||||
#include <blt/std/logging.h>
|
||||
#include <iostream>
|
||||
#include <ios>
|
||||
#include <blt_tests.h>
|
||||
#include <cmath>
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
|
||||
using vec3fp = blt::vec<blt::fp64, 3>;
|
||||
|
||||
namespace blt::test
|
||||
{
|
||||
void print(fp64 v, const std::string& name = "")
|
||||
{
|
||||
std::cout << name << " [" << v.raw() << ':' << std::hex << v.raw() << std::dec << "]\tu64(" << v.as_u64() << ")\ti64(" << v.as_i64()
|
||||
<< ")\tu32(" << v.as_u32() << ")\ti32(" << v.as_i32() << ")\tf32("
|
||||
<< std::setprecision(std::numeric_limits<long double>::digits10 + 1)
|
||||
<< std::setw(16) << std::fixed << v.as_f32() << ")\tf64(" << v.as_f64() << ")\n";
|
||||
}
|
||||
|
||||
void fixed_point()
|
||||
{
|
||||
//vec3fp hello = {fp64::from_f64(32.023), fp64::from_f64(422.34023), fp64::from_f64(321.023)};
|
||||
|
||||
print(FP64_UMAX, "umax");
|
||||
print(FP64_UMIN, "umin");
|
||||
print(FP64_IMAX, "imax");
|
||||
print(FP64_IMIN, "imin");
|
||||
print(FP64_FMAX, "fmax");
|
||||
print(FP64_FMIN, "fmin");
|
||||
print(FP64_EPSILON, "epis");
|
||||
print(FP64_PI, "pi ");
|
||||
print(FP64_PI_2, "pi2 ");
|
||||
print(FP64_PI_4, "pi4 ");
|
||||
print(FP64_1_PI, "1/pi");
|
||||
print(FP64_2_PI, "1/p2");
|
||||
print(FP64_SQRT2, "sqr2");
|
||||
print(FP64_1_SQRT2, "isq2");
|
||||
print(FP64_E, "e ");
|
||||
print(FP64_LOG2E, "logE");
|
||||
|
||||
fp64 uv = fp64::from_u64(32);
|
||||
fp64 iv = fp64::from_i64(16);
|
||||
|
||||
fp64 fv = fp64::from_f32(53.4234234);
|
||||
fp64 pi = fp64::from_f64(M_PI);
|
||||
|
||||
std::cout << "[" << static_cast<u64>(uv) << "]: " << uv.as_i64() << " : " << uv.as_u64() << " : " << uv.as_f64() << std::endl;
|
||||
std::cout << "[" << static_cast<u64>(iv) << "]: " << iv.as_i64() << " : " << iv.as_u64() << " : " << iv.as_f64() << std::endl;
|
||||
std::cout << "[" << static_cast<u64>(fv) << "]: " << fv.as_i64() << " : " << fv.as_u64() << " : " << fv.as_f64() << std::endl;
|
||||
std::cout << "[" << static_cast<u64>(pi) << "]: " << pi.as_i64() << " : " << pi.as_u64() << " : " << pi.as_f64() << std::endl;
|
||||
print(uv * iv, "32 * 16");
|
||||
print(uv / iv, "32 / 16");
|
||||
print(fv / pi, "53.4234234 / pi");
|
||||
|
||||
std::cout << (uv * iv).as_i64() << std::endl;
|
||||
std::cout << (uv * iv).as_u64() << std::endl;
|
||||
std::cout << (uv / iv).as_i64() << std::endl;
|
||||
std::cout << (uv / iv).as_u64() << std::endl;
|
||||
print(uv + iv, "32 + 16");
|
||||
print(uv - iv, "32 - 16");
|
||||
|
||||
print(fp64::from_f32(32.43242), "32.43242");
|
||||
print(fp64::from_f64(634.2349932493423), "634.2349932493423");
|
||||
print(fp64::from_u32(3194967295), "3194967295");
|
||||
print(fp64::from_i32(-1194967295), "-1194967295");
|
||||
print(fp64::from_i64(-13194967295), "-13194967295");
|
||||
print(fp64::from_u64(66294967295), "66294967295");
|
||||
|
||||
uv *= fp64::from_i32(-32);
|
||||
|
||||
print(uv);
|
||||
|
||||
uv /= fp64::from_i32(-16);
|
||||
|
||||
print(uv);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue