move fixed point number class to separate file

This commit is contained in:
Wolfgang Thaller 2012-04-10 23:23:21 +02:00
parent 793b94bacc
commit 52b50689d2
4 changed files with 160 additions and 103 deletions

View File

@ -9,7 +9,9 @@ add_executable(Raytracer MACOSX_BUNDLE
raytracer.cc
)
add_executable(Raytracer2 MACOSX_BUNDLE
raytracer2.cc
raytracer2.cc
fixed.h
fixed.cc
)

29
Raytracer/fixed.cc Normal file
View File

@ -0,0 +1,29 @@
#include "fixed.h"
long fixed::nMul = 0, fixed::nIMul = 0, fixed::nDiv = 0, fixed::nSqrt = 0;
fixed sqrt(fixed f)
{
COUNT_OP(fixed::nSqrt);
const int FRACBITS = 16; /* Must be even! */
const int ITERS = 15 + (FRACBITS >> 1);
unsigned long root, remHi, remLo, testDiv, count;
root = 0; /* Clear root */
remHi = 0; /* Clear high part of partial remainder */
remLo = f.val; /* Get argument into low part of partial remainder */
count = ITERS; /* Load loop counter */
do {
remHi = (remHi << 2) | (remLo >> 30); remLo <<= 2; /* get 2 bits of arg */
root <<= 1; /* Get ready for the next bit in the root */
testDiv = (root << 1) + 1; /* Test radical */
if (remHi >= testDiv) {
remHi -= testDiv;
root += 1;
}
} while (count-- != 0);
return fixed(root, fixed::raw());
}

119
Raytracer/fixed.h Normal file
View File

@ -0,0 +1,119 @@
#ifndef FIXED_H
#define FIXED_H
#include <cstdint>
inline std::int32_t muls(std::int16_t x, std::int16_t y)
{
return (std::int32_t)x*y;
}
inline std::uint32_t mulu(std::uint16_t x, std::uint16_t y)
{
//return (std::uint32_t)x * y;
std::uint32_t res;
__asm("mulu %1, %0" : "=d"(res) : "d"(x), "0"(y));
return res;
}
inline std::int32_t mulsu(std::int16_t x, std::uint16_t y)
{
//return (std::int32_t)a * (std::uint32_t)b;
std::int32_t res;
__asm("mulu %1, %0" : "=d"(res) : "d"(x), "0"(y));
if(x < 0)
res -= ((std::uint32_t)y) << 16;
return res;
}
#define COUNT_OP(var) ++var
class fixed
{
std::int32_t val;
public:
class raw {};
fixed(std::int32_t val, raw r) : val(val) {}
fixed() : val(0) {}
fixed(int x) : val((long)x << 16) {}
fixed(float f) : val(f * 65536) {}
//operator int() { return val >> 16; }
fixed operator+(fixed o) const { return fixed(val + o.val, raw()); }
fixed operator-(fixed o) const { return fixed(val - o.val, raw()); }
fixed operator*(fixed o) const {
COUNT_OP(nMul);
//return fixed((static_cast<long long>(val) * o.val) >> 16, raw());
int16_t a = val >> 16;
int16_t c = o.val >> 16;
uint16_t b = val;
uint16_t d = o.val;
return fixed(((a*c) << 16)
+ mulsu(a,d) + mulsu(c,b)
+ (mulu(b,d) >> 16),raw());
}
fixed operator/(fixed o) const { COUNT_OP(nDiv); return fixed((static_cast<long long>(val) << 16) / o.val, raw()); }
fixed operator-() const { return fixed(-val, raw()); }
fixed& operator+=(fixed o) { val += o.val; return *this; }
fixed& operator-=(fixed o) { val -= o.val; return *this; }
fixed& operator*=(fixed o) { return (*this = *this * o); }
bool operator== (fixed o) const { return val == o.val; }
bool operator!= (fixed o) const { return val != o.val; }
bool operator> (fixed o) const { return val > o.val; }
bool operator< (fixed o) const { return val < o.val; }
bool operator>= (fixed o) const { return val >= o.val; }
bool operator<= (fixed o) const { return val <= o.val; }
friend fixed sqrt(fixed f);
friend fixed floor(fixed f);
friend fixed operator*(fixed f, int x);
friend fixed operator*(int x, fixed f);
friend int floor_to_int(fixed f);
static long nMul;
static long nIMul;
static long nDiv;
static long nSqrt;
};
/*fixed operator*(fixed f, int x) { return fixed(f.val * x, fixed::raw()); }
fixed operator*(int x, fixed f) { return fixed(f.val * x, fixed::raw()); }*/
inline fixed operator*(fixed f, int c)
{
std::int16_t a = f.val >> 16;
std::uint16_t b = f.val;
COUNT_OP(fixed::nIMul);
return fixed(((a*c) << 16)
+ mulsu(c,b),fixed::raw());
}
inline fixed operator*(int x, fixed f) { return f*x; }
inline fixed operator*(fixed f, float x) { return f*fixed(x); }
inline fixed operator*(float x, fixed f) { return f*fixed(x); }
fixed sqrt(fixed f);
inline fixed floor(fixed f)
{
return fixed(f.val & 0xFFFF0000L, fixed::raw());
}
inline int floor_to_int(fixed f)
{
return f.val >> 16;
}
#endif // FIXED_H

View File

@ -21,6 +21,7 @@ QDGlobals qd;
#endif
#include "fixed.h"
#include <cmath>
#include <algorithm>
@ -31,103 +32,9 @@ QDGlobals qd;
using std::sqrt;
using std::floor;
class fixed
{
long val;
public:
class raw {};
fixed(long val, raw r) : val(val) {}
fixed() : val(0) {}
fixed(int x) : val((long)x << 16) {}
fixed(float f) : val(f * 65536) {}
//operator int() { return val >> 16; }
fixed operator+(fixed o) const { return fixed(val + o.val, raw()); }
fixed operator-(fixed o) const { return fixed(val - o.val, raw()); }
fixed operator*(fixed o) const { return fixed((static_cast<long long>(val) * o.val) >> 16, raw()); }
fixed operator/(fixed o) const { return fixed((static_cast<long long>(val) << 16) / o.val, raw()); }
fixed operator-() const { return fixed(-val, raw()); }
fixed& operator+=(fixed o) { val += o.val; return *this; }
fixed& operator-=(fixed o) { val -= o.val; return *this; }
fixed& operator*=(fixed o) { return (*this = *this * o); }
bool operator== (fixed o) const { return val == o.val; }
bool operator!= (fixed o) const { return val != o.val; }
bool operator> (fixed o) const { return val > o.val; }
bool operator< (fixed o) const { return val < o.val; }
bool operator>= (fixed o) const { return val >= o.val; }
bool operator<= (fixed o) const { return val <= o.val; }
friend fixed sqrt(fixed f);
friend fixed floor(fixed f);
friend fixed operator*(fixed f, int x);
friend fixed operator*(int x, fixed f);
friend int floor_to_int(fixed f);
};
fixed operator*(fixed f, int x) { return fixed(f.val * x, fixed::raw()); }
fixed operator*(int x, fixed f) { return fixed(f.val * x, fixed::raw()); }
fixed operator*(fixed f, float x) { return f*fixed(x); }
fixed operator*(float x, fixed f) { return f*fixed(x); }
fixed sqrt(fixed f)
{
#if 1
const int FRACBITS = 16; /* Must be even! */
const int ITERS = 15 + (FRACBITS >> 1);
unsigned long root, remHi, remLo, testDiv, count;
root = 0; /* Clear root */
remHi = 0; /* Clear high part of partial remainder */
remLo = f.val; /* Get argument into low part of partial remainder */
count = ITERS; /* Load loop counter */
do {
remHi = (remHi << 2) | (remLo >> 30); remLo <<= 2; /* get 2 bits of arg */
root <<= 1; /* Get ready for the next bit in the root */
testDiv = (root << 1) + 1; /* Test radical */
if (remHi >= testDiv) {
remHi -= testDiv;
root += 1;
}
} while (count-- != 0);
return fixed(root, fixed::raw());
#else
fixed lower = 0;
fixed upper = 181; // 181.019
while(lower != upper)
{
fixed mid(lower.val/2 + upper.val/2, fixed::raw());
fixed s = mid*mid;
if(s <= f)
lower = mid;
if(s >= f)
upper = mid;
}
return lower;
#endif
}
fixed floor(fixed f)
{
return fixed(f.val & 0xFFFF0000L, fixed::raw());
}
int floor_to_int(fixed f)
{
return f.val >> 16;
}
int floor_to_int(float f)
inline int floor_to_int(float f)
{
return static_cast<int>(std::floor(f));
}
@ -169,8 +76,8 @@ public:
template<class T>
bool hitSphere(vec3<T> p0, vec3<T> dir, T& t)
{
const vec3<T> center(0.0f, 0.0f, -6.0f);
const T r = 1.0f;
const vec3<T> center(0.0f, 1.0f, -6.0f);
const T r = 2.0f;
vec3<T> p0c(p0 - center);
/*
@ -202,8 +109,8 @@ T ray(int n, vec3<T> p0, vec3<T> dir)
static const vec3<T> light = vec3<T>(-2,4,3).normalize();
if(1){
const vec3<T> center(0.0f, 0.0f, -6.0f);
const T r = 1.0f;
const vec3<T> center(0.0f, 1.0f, -6.0f);
const T r = 2.0f;
vec3<T> p0c(p0 - center);
/*
@ -226,7 +133,7 @@ T ray(int n, vec3<T> p0, vec3<T> dir)
{
vec3<T> p = p0 + dir * t;
vec3<T> dir2 = p - center;
vec3<T> dir2 = (p - center) * (T(1)/r);
T l = dir2*dir;
@ -290,7 +197,6 @@ struct rand1<fixed>
int main()
{
WindowPtr win;
Debugger();
#if !TARGET_API_MAC_CARBON
InitGraf(&qd.thePort);
InitFonts();
@ -366,7 +272,8 @@ int main()
char buf[256];
unsigned char* pstr = (unsigned char*)buf;
std::sprintf(buf+1, "pps = %d", (int)( (long)r.right * r.bottom * 60 / (endTime - startTime) ));
std::sprintf(buf+1, "pps = %d %ld %ld %ld %ld", (int)( (long)r.right * r.bottom * 60 / (endTime - startTime) ),
fixed::nMul, fixed::nIMul, fixed::nDiv, fixed::nSqrt);
buf[0] = std::strlen(buf+1);
SetRect(&r, 10, 10, 10 + StringWidth(pstr) + 10, 30);