Name: Anonymous 2010-07-05 16:04
Design a fast square root function which computes double floating point numbers faster than SQRTSD(SSE2). Bonus for precision.
inline double zoom_zoom_sqrt(int _)
{
return 0.0;
}#define sqrt_float(a) (1.f)1.fstatic inline uintmax_t isqrt(uintmax_t n){
uintmax_t r = 0;
// fixed this so it should work even if uintmax_t is an odd number of bits!
// ... i've never seen an implementation where that's the case, but i realized
// that the code i had here before would break if someone was perverse enough
// to do that, so i fixed it.
for(uintmax_t i = ~(UINTMAX_MAX >> 2) & UINTMAX_MAX / 3; i; i >>= 2)
if(n >= (i | r)){
n -= i | r;
r = r >> 1 | i;
} else r >>= 1;
return r;
}
// 6 digits after the decimal point for floating-point-using idiots:
#define SQRT(n) (isqrt((uintmax_t)(n) * 1000000000000ULL /* 100⁶ */) / 1000000.0L /* 10⁶ */)double sqrts[18446744073709551616] = {
/* the contents of this array are left as an exercise for the reader */
double fastsqrt(double f) {
int64_t *idx = (int64_t*)&f;
return sqrts[*idx];
}
static inline uintmax_t isqrt(uintmax_t) __attribute__ ((const, nothrow, optimize(2)));
static inline uintmax_t isqrt(uintmax_t n)
{ static const uintmax_t start = ~(UINTMAX_MAX >> 2) & UINTMAX_MAX / 3;
uintmax_t r = 0;
for(uintmax_t t, i = start; i; i >>= 2)
{ t = i | r;
r >>= 1;
if(t > n)
{ n -= t;
r |= i; }}
return r; }
static inline uintmax_t isqrt(uintmax_t) __attribute__ ((const, nothrow, optimize(2)));
static inline uintmax_t isqrt(uintmax_t n)
{ static const uintmax_t start = ~(UINTMAX_MAX >> 2) & UINTMAX_MAX / 3;
uintmax_t r = 0;
for(uintmax_t t, i = start; i; i >>= 2)
{ t = i | r;
r >>= 1;
if(t > n)
{ n -= t;
r |= i; }}
return r; }invsqrt from Quake.
float Q_rsqrt( float number )
{
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y; // evil floating point bit level hacking
i = 0x5f3759df - ( i >> 1 ); // what the fuck?
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
#ifndef Q3_VM
#ifdef __linux__
assert( !isnan(y) ); // bk010122 - FPE?
#endif
#endif
return y;
}
double sqrt(double n) { return n; }bool sqrt(double n, double r){ return n * n == r; }
(define (SQRT) f=X/y, f=y )
function result = sqrtX(n)
solval = 0;
tartval = 1;
check = n - (tartval*tartval);
while(abs(check) > 0.01)
solval = check / (tartval * 2);
tartval = tartval + solval;
check = n - (tartval*tartval);
endwhile;
result = tartval;
endfunction