summaryrefslogtreecommitdiff
path: root/apps/plugins/puzzles
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2017-08-17 17:14:21 -0400
committerFranklin Wei <git@fwei.tk>2017-08-23 14:22:09 -0400
commitec1a74a37c43763e9d24f6dbb578811a7947d5c5 (patch)
tree88ea724d1553442f761e43318d392fabd7f11d92 /apps/plugins/puzzles
parentf2f1889b108ad85ccfeedff6afcb4a98e06c5580 (diff)
downloadrockbox-ec1a74a37c43763e9d24f6dbb578811a7947d5c5.tar.gz
rockbox-ec1a74a37c43763e9d24f6dbb578811a7947d5c5.zip
puzzles: faster, smaller sqrt()
Change-Id: I18e170ee49bff131fe76fa4bb1b9e0f120818b82
Diffstat (limited to 'apps/plugins/puzzles')
-rw-r--r--apps/plugins/puzzles/rbwrappers.c70
1 files changed, 8 insertions, 62 deletions
diff --git a/apps/plugins/puzzles/rbwrappers.c b/apps/plugins/puzzles/rbwrappers.c
index 2d857c1cc9..feb1bf79de 100644
--- a/apps/plugins/puzzles/rbwrappers.c
+++ b/apps/plugins/puzzles/rbwrappers.c
@@ -984,70 +984,16 @@ float atan2_wrapper(float y, float x)
984 } 984 }
985} 985}
986 986
987/* Square root function, original. */
988float sqrt_wrapper(float x) 987float sqrt_wrapper(float x)
989{ 988{
990 float z; 989 /* find inverse, Quake-style */
991 int32_t sign = (int)0x80000000; 990 float xhalf = .5f * x;
992 int32_t ix,s,q,m,t,i; 991 int i = *(int*)&x;
993 uint32_t r; 992 i = 0x5f3759df - (i >> 1);
994 993 x = *(float*)&i;
995 GET_FLOAT_WORD(ix,x); 994 x = x * (1.5f - (xhalf * x * x));
996 995
997 /* take care of Inf and NaN */ 996 return 1.0f / x;
998 if((ix&0x7f800000)==0x7f800000) {
999 return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
1000 sqrt(-inf)=sNaN */
1001 }
1002 /* take care of zero */
1003 if(ix<=0) {
1004 if((ix&(~sign))==0) return x;/* sqrt(+-0) = +-0 */
1005 else if(ix<0)
1006 return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
1007 }
1008 /* normalize x */
1009 m = (ix>>23);
1010 if(m==0) { /* subnormal x */
1011 for(i=0;(ix&0x00800000)==0;i++) ix<<=1;
1012 m -= i-1;
1013 }
1014 m -= 127; /* unbias exponent */
1015 ix = (ix&0x007fffff)|0x00800000;
1016 if(m&1) /* odd m, double x to make it even */
1017 ix += ix;
1018 m >>= 1; /* m = [m/2] */
1019
1020 /* generate sqrt(x) bit by bit */
1021 ix += ix;
1022 q = s = 0; /* q = sqrt(x) */
1023 r = 0x01000000; /* r = moving bit from right to left */
1024
1025 while(r!=0) {
1026 t = s+r;
1027 if(t<=ix) {
1028 s = t+r;
1029 ix -= t;
1030 q += r;
1031 }
1032 ix += ix;
1033 r>>=1;
1034 }
1035
1036 /* use floating add to find out rounding direction */
1037 if(ix!=0) {
1038 z = one-tiny; /* trigger inexact flag */
1039 if (z>=one) {
1040 z = one+tiny;
1041 if (z>one)
1042 q += 2;
1043 else
1044 q += (q&1);
1045 }
1046 }
1047 ix = (q>>1)+0x3f000000;
1048 ix += (m <<23);
1049 SET_FLOAT_WORD(z,ix);
1050 return z;
1051} 997}
1052 998
1053/* hack, simple trig */ 999/* hack, simple trig */