⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 invsqrt.c

📁 [Game.Programming].Academic - Graphics Gems (6 books source code)
💻 C
字号:
/* Compute the Inverse Square Root * of an IEEE Single Precision Floating-Point number. * * Written by Ken Turkowski. *//* Specified parameters */#define LOOKUP_BITS    6   /* Number of mantissa bits for lookup */#define EXP_POS       23   /* Position of the exponent */#define EXP_BIAS     127   /* Bias of exponent *//* The mantissa is assumed to be just down from the exponent *//* Type of result */#ifndef DOUBLE_PRECISION typedef float FLOAT;#else /* DOUBLE_PRECISION */ typedef double FLOAT;#endif /* DOUBLE_PRECISION *//* Derived parameters */#define LOOKUP_POS   (EXP_POS-LOOKUP_BITS)  /* Position of mantissa lookup */#define SEED_POS     (EXP_POS-8)            /* Position of mantissa seed */#define TABLE_SIZE   (2 << LOOKUP_BITS)     /* Number of entries in table */#define LOOKUP_MASK  (TABLE_SIZE - 1)           /* Mask for table input */#define GET_EXP(a)   (((a) >> EXP_POS) & 0xFF)  /* Extract exponent */#define SET_EXP(a)   ((a) << EXP_POS)           /* Set exponent */#define GET_EMANT(a) (((a) >> LOOKUP_POS) & LOOKUP_MASK)  /* Extended mantissa                                                           * MSB's */#define SET_MANTSEED(a) (((unsigned long)(a)) << SEED_POS)  /* Set mantissa                                                             * 8 MSB's */#include <stdlib.h>#include <math.h>static unsigned char *iSqrt = NULL;union _flint {    unsigned long    i;    float            f;} _fi, _fo;static voidMakeInverseSqrtLookupTable(void){    register long f;    register unsigned char *h;    union _flint fi, fo;    iSqrt = malloc(TABLE_SIZE);    h = iSqrt;    for (f = 0, h = iSqrt; f < TABLE_SIZE; f++) {        fi.i = ((EXP_BIAS-1) << EXP_POS) | (f << LOOKUP_POS);        fo.f = 1.0 / sqrt(fi.f);        *h++ = ((fo.i + (1<<(SEED_POS-2))) >> SEED_POS) & 0xFF; /* rounding */    }    iSqrt[TABLE_SIZE / 2] = 0xFF;    /* Special case for 1.0 */}/* The following returns the inverse square root */FLOATInvSqrt(float x){    register unsigned long a = ((union _flint*)(&x))->i;    register float arg = x;    union _flint seed;    register FLOAT r;    if (iSqrt == NULL) MakeInverseSqrtLookupTable();    seed.i = SET_EXP(((3*EXP_BIAS-1) - GET_EXP(a)) >> 1)           | SET_MANTSEED(iSqrt[GET_EMANT(a)]);    /* Seed: accurate to LOOKUP_BITS */    r = seed.f;    /* First iteration: accurate to 2*LOOKUP_BITS */    r = (3.0 - r * r * arg) * r * 0.5;    /* Second iteration: accurate to 4*LOOKUP_BITS */    r = (3.0 - r * r * arg) * r * 0.5;#ifdef DOUBLE_PRECISION    /* Third iteration: accurate to 8*LOOKUP_BITS */    r = (3.0 - r * r * arg) * r * 0.5;#endif /* DOUBLE_PRECISION */    return(r);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -