Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #3259

Re: Java left shift and right shift operators.

Path csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!news.albasani.net!eternal-september.org!feeder.eternal-september.org!.POSTED!not-for-mail
From Joshua Cranmer <Pidgeot18@verizon.invalid>
Newsgroups comp.lang.java.programmer
Subject Re: Java left shift and right shift operators.
Date Tue, 26 Apr 2011 08:41:30 -0400
Organization A noiseless patient Spider
Lines 236
Message-ID <ip6ehu$qia$1@dont-email.me> (permalink)
References <295e16b3-2ed8-4529-bfb0-1cc26ed93ad6@d26g2000prn.googlegroups.com>
Mime-Version 1.0
Content-Type text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding 7bit
Injection-Date Tue, 26 Apr 2011 12:41:35 +0000 (UTC)
Injection-Info mx01.eternal-september.org; posting-host="LtjcJP1H6uHOtkcPMh0bUA"; logging-data="27210"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19l4qbuOLfp1T8BCmrrd5D+SQlYHNTgZp8="
User-Agent Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.16pre) Gecko/20110305 Lightning/1.0b3pre Thunderbird/3.1.10pre
In-Reply-To <295e16b3-2ed8-4529-bfb0-1cc26ed93ad6@d26g2000prn.googlegroups.com>
Cancel-Lock sha1:yIHVdFBH7ozBtkLB3tkIqpJSLBM=
Xref x330-a1.tempe.blueboxinc.net comp.lang.java.programmer:3259

Show key headers only | View raw


On 04/26/2011 03:38 AM, Sanny wrote:
> divider=2^shiftby; //<<=== Is it not 2*2* ... shiftby times????
  the `^' here is the XOR operator, not an exponentiation operator.

> math.pow() is again time consuming function. Can I use it? how much
> faster is math.pow() function compared to if conditions?

Math.pow is S - L - O - W compared to an if and a shift. Barrel shifting 
can be done in the same amount of time as integer addition (circuit 
depth is both  O(lg N) in both cases), while Math.pow is a function that 
works with floating point (typically slower than integer math anyways), 
has lower precision (53 bits for double, 63 bits for long), and requires 
a lot more computation. This is a listing I have for the implementation 
of Math.pow, courtesy of OpenJDK:

double __ieee754_pow(double x, double y)
{
         double z,ax,z_h,z_l,p_h,p_l;
         double y1,t1,t2,r,s,t,u,v,w;
         int i0,i1,i,j,k,yisint,n;
         int hx,hy,ix,iy;
         unsigned lx,ly;

         i0 = ((*(int*)&one)>>29)^1; i1=1-i0;
         hx = __HI(x); lx = __LO(x);
         hy = __HI(y); ly = __LO(y);
         ix = hx&0x7fffffff;  iy = hy&0x7fffffff;

     /* y==zero: x**0 = 1 */
         if((iy|ly)==0) return one;

     /* +-NaN return x+y */
         if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) ||
            iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0)))
                 return x+y;

     /* determine if y is an odd int when x < 0
      * yisint = 0       ... y is not an integer
      * yisint = 1       ... y is an odd int
      * yisint = 2       ... y is an even int
      */
         yisint  = 0;
         if(hx<0) {
             if(iy>=0x43400000) yisint = 2; /* even integer y */
             else if(iy>=0x3ff00000) {
                 k = (iy>>20)-0x3ff;        /* exponent */
                 if(k>20) {
                     j = ly>>(52-k);
                     if((j<<(52-k))==ly) yisint = 2-(j&1);
                 } else if(ly==0) {
                     j = iy>>(20-k);
                     if((j<<(20-k))==iy) yisint = 2-(j&1);
                 }
             }
         }

     /* special value of y */
         if(ly==0) {
             if (iy==0x7ff00000) {       /* y is +-inf */
                 if(((ix-0x3ff00000)|lx)==0)
                     return  y - y;      /* inf**+-1 is NaN */
                 else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */
                     return (hy>=0)? y: zero;
                 else                    /* (|x|<1)**-,+inf = inf,0 */
                     return (hy<0)?-y: zero;
             }
             if(iy==0x3ff00000) {        /* y is  +-1 */
                 if(hy<0) return one/x; else return x;
             }
             if(hy==0x40000000) return x*x; /* y is  2 */
             if(hy==0x3fe00000) {        /* y is  0.5 */
                 if(hx>=0)       /* x >= +0 */
                 return sqrt(x);
             }
         }

         ax   = fabs(x);
     /* special value of x */
         if(lx==0) {
             if(ix==0x7ff00000||ix==0||ix==0x3ff00000){
                 z = ax;                 /*x is +-0,+-inf,+-1*/
                 if(hy<0) z = one/z;     /* z = (1/|x|) */
                 if(hx<0) {
                     if(((ix-0x3ff00000)|yisint)==0) {
                         z = (z-z)/(z-z); /* (-1)**non-int is NaN */
                     } else if(yisint==1)
                         z = -1.0*z;             /* (x<0)**odd = 
-(|x|**odd) */
                 }
                 return z;
             }
         }

         n = (hx>>31)+1;

     /* (x<0)**(non-int) is NaN */
         if((n|yisint)==0) return (x-x)/(x-x);

         s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
         if((n|(yisint-1))==0) s = -one;/* (-ve)**(odd int) */

     /* |y| is huge */
         if(iy>0x41e00000) { /* if |y| > 2**31 */
             if(iy>0x43f00000){  /* if |y| > 2**64, must o/uflow */
                 if(ix<=0x3fefffff) return (hy<0)? huge*huge:tiny*tiny;
                 if(ix>=0x3ff00000) return (hy>0)? huge*huge:tiny*tiny;
             }
         /* over/underflow if x is not close to one */
             if(ix<0x3fefffff) return (hy<0)? s*huge*huge:s*tiny*tiny;
             if(ix>0x3ff00000) return (hy>0)? s*huge*huge:s*tiny*tiny;
         /* now |1-x| is tiny <= 2**-20, suffice to compute
            log(x) by x-x^2/2+x^3/3-x^4/4 */
             t = ax-one;         /* t has 20 trailing zeros */
             w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25));
             u = ivln2_h*t;      /* ivln2_h has 21 sig. bits */
             v = t*ivln2_l-w*ivln2;
             t1 = u+v;
             __LO(t1) = 0;
             t2 = v-(t1-u);
         } else {
             double ss,s2,s_h,s_l,t_h,t_l;
             n = 0;
         /* take care subnormal number */
             if(ix<0x00100000)
                 {ax *= two53; n -= 53; ix = __HI(ax); }
             n  += ((ix)>>20)-0x3ff;
             j  = ix&0x000fffff;
         /* determine interval */
             ix = j|0x3ff00000;          /* normalize ix */
             if(j<=0x3988E) k=0;         /* |x|<sqrt(3/2) */
             else if(j<0xBB67A) k=1;     /* |x|<sqrt(3)   */
             else {k=0;n+=1;ix -= 0x00100000;}
             __HI(ax) = ix;

         /* compute ss = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
             u = ax-bp[k];               /* bp[0]=1.0, bp[1]=1.5 */
             v = one/(ax+bp[k]);
             ss = u*v;
             s_h = ss;
             __LO(s_h) = 0;
         /* t_h=ax+bp[k] High */
             t_h = zero;
             __HI(t_h)=((ix>>1)|0x20000000)+0x00080000+(k<<18);
             t_l = ax - (t_h-bp[k]);
             s_l = v*((u-s_h*t_h)-s_h*t_l);
         /* compute log(ax) */
             s2 = ss*ss;
             r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
             r += s_l*(s_h+ss);
             s2  = s_h*s_h;
             t_h = 3.0+s2+r;
             __LO(t_h) = 0;
             t_l = r-((t_h-3.0)-s2);
         /* u+v = ss*(1+...) */
             u = s_h*t_h;
             v = s_l*t_h+t_l*ss;
         /* 2/(3log2)*(ss+...) */
             p_h = u+v;
             __LO(p_h) = 0;
             p_l = v-(p_h-u);
             z_h = cp_h*p_h;             /* cp_h+cp_l = 2/(3*log2) */
             z_l = cp_l*p_h+p_l*cp+dp_l[k];
         /* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */
             t = (double)n;
             t1 = (((z_h+z_l)+dp_h[k])+t);
             __LO(t1) = 0;
             t2 = z_l-(((t1-t)-dp_h[k])-z_h);
         }

     /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
         y1  = y;
         __LO(y1) = 0;
         p_l = (y-y1)*t1+y*t2;
         p_h = y1*t1;
         z = p_l+p_h;
         j = __HI(z);
         i = __LO(z);
         if (j>=0x40900000) {                            /* z >= 1024 */
             if(((j-0x40900000)|i)!=0)                   /* if z > 1024 */
                 return s*huge*huge;                     /* overflow */
             else {
                 if(p_l+ovt>z-p_h) return s*huge*huge;   /* overflow */
             }
         } else if((j&0x7fffffff)>=0x4090cc00 ) {        /* z <= -1075 */
             if(((j-0xc090cc00)|i)!=0)           /* z < -1075 */
                 return s*tiny*tiny;             /* underflow */
             else {
                 if(p_l<=z-p_h) return s*tiny*tiny;      /* underflow */
             }
         }
     /*
      * compute 2**(p_h+p_l)
      */
         i = j&0x7fffffff;
         k = (i>>20)-0x3ff;
         n = 0;
         if(i>0x3fe00000) {              /* if |z| > 0.5, set n = [z+0.5] */
             n = j+(0x00100000>>(k+1));
             k = ((n&0x7fffffff)>>20)-0x3ff;     /* new k for n */
             t = zero;
             __HI(t) = (n&~(0x000fffff>>k));
             n = ((n&0x000fffff)|0x00100000)>>(20-k);
             if(j<0) n = -n;
             p_h -= t;
         }
         t = p_l+p_h;
         __LO(t) = 0;
         u = t*lg2_h;
         v = (p_l-(t-p_h))*lg2+t*lg2_l;
         z = u+v;
         w = v-(z-u);
         t  = z*z;
         t1  = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
         r  = (z*t1)/(t1-two)-(w+z*w);
         z  = one-(r-z);
         j  = __HI(z);
         j += (n<<20);
         if((j>>20)<=0) z = scalbn(z,n); /* subnormal output */
         else __HI(z) += (n<<20);
         return s*z;
}

Well over a hundred lines of code, and consisting minimally of 1 if 
statement and maximally of around 2-3 dozen if statements.

All to avoid a single if statement? I think not.

With modern branch prediction, you'd probably lose out an amortized cost 
of a dozen clock cycles or so with that branch prediction, and there are 
some systems where the branch essentially becomes free (good candidate 
for predicates). If you're really that worried about a single if 
statement, then the sanity checks on your input parameters must be 
killing you.
-- 
Beware of bugs in the above code; I have only proved it correct, not 
tried it. -- Donald E. Knuth

Back to comp.lang.java.programmer | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

Java left shift and right shift operators. Sanny <softtanks22@hotmail.com> - 2011-04-26 00:38 -0700
  Re: Java left shift and right shift operators. Lothar Kimmeringer <news200709@kimmeringer.de> - 2011-04-26 09:55 +0200
    Re: Java left shift and right shift operators. Patricia Shanahan <pats@acm.org> - 2011-04-26 03:16 -0700
    Re: Java left shift and right shift operators. Lew <noone@lewscanon.com> - 2011-04-26 09:49 -0400
      Re: Java left shift and right shift operators. Travers Naran <tnaran@gmail.com> - 2011-04-26 07:09 -0700
        Re: Java left shift and right shift operators. Lew <noone@lewscanon.com> - 2011-04-26 11:21 -0400
        Re: Java left shift and right shift operators. Martin Gregorie <martin@address-in-sig.invalid> - 2011-04-26 15:37 +0000
      Re: Java left shift and right shift operators. Sanny <softtanks22@hotmail.com> - 2011-04-26 09:32 -0700
        Re: Java left shift and right shift operators. Patricia Shanahan <pats@acm.org> - 2011-04-26 11:09 -0700
          Re: Java left shift and right shift operators. Patricia Shanahan <pats@acm.org> - 2011-04-26 13:09 -0700
        Re: Java left shift and right shift operators. Travers Naran <tnaran@gmail.com> - 2011-04-26 22:40 -0700
          Re: Java left shift and right shift operators. Patricia Shanahan <pats@acm.org> - 2011-04-27 05:34 -0700
            Re: Java left shift and right shift operators. Owen Jacobson <angrybaldguy@gmail.com> - 2011-04-28 00:37 -0400
              Re: Java left shift and right shift operators. Patricia Shanahan <pats@acm.org> - 2011-04-28 16:02 -0700
              Re: Java left shift and right shift operators. Michael Wojcik <mwojcik@newsguy.com> - 2011-04-28 19:22 -0400
          Re: Java left shift and right shift operators. bugbear <bugbear@trim_papermule.co.uk_trim> - 2011-04-27 14:28 +0100
          Re: Java left shift and right shift operators. Thomas Richter <thor@math.tu-berlin.de> - 2011-04-30 00:02 +0200
      Re: Java left shift and right shift operators. Roedy Green <see_website@mindprod.com.invalid> - 2011-04-27 19:25 -0700
        Re: Java left shift and right shift operators. Lew <noone@lewscanon.com> - 2011-04-27 23:08 -0400
  Re: Java left shift and right shift operators. Sanny <softtanks22@hotmail.com> - 2011-04-26 02:04 -0700
    Re: Java left shift and right shift operators. Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-04-26 07:34 -0400
      Re: Java left shift and right shift operators. Lew <noone@lewscanon.com> - 2011-04-26 09:47 -0400
        Re: Java left shift and right shift operators. Patricia Shanahan <pats@acm.org> - 2011-04-27 09:23 -0700
          Re: Java left shift and right shift operators. Lew <noone@lewscanon.com> - 2011-04-27 14:49 -0400
            Re: Java left shift and right shift operators. Paul Cager <paul.cager@googlemail.com> - 2011-04-27 17:28 -0700
              Re: Java left shift and right shift operators. Lew <noone@lewscanon.com> - 2011-04-27 22:06 -0400
      Re: Java left shift and right shift operators. Sanny <softtanks22@hotmail.com> - 2011-04-26 09:39 -0700
        Re: Java left shift and right shift operators. Patricia Shanahan <pats@acm.org> - 2011-04-26 11:17 -0700
        Re: Java left shift and right shift operators. Lew <noone@lewscanon.com> - 2011-04-26 14:55 -0400
          Re: Java left shift and right shift operators. Lew <noone@lewscanon.com> - 2011-04-26 14:57 -0400
          Re: Java left shift and right shift operators. Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-04-26 21:38 +0200
          Re: Java left shift and right shift operators. Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2011-04-26 23:32 +0000
            Re: Java left shift and right shift operators. Lew <noone@lewscanon.com> - 2011-04-27 00:08 -0400
              Re: Java left shift and right shift operators. Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2011-04-27 06:57 +0000
                Re: Java left shift and right shift operators. Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-04-27 07:00 -0300
                Re: Java left shift and right shift operators. Lew <noone@lewscanon.com> - 2011-04-27 08:42 -0400
                Re: Java left shift and right shift operators. Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2011-04-27 14:03 +0000
                Re: Java left shift and right shift operators. Lew <noone@lewscanon.com> - 2011-04-27 14:54 -0400
        Re: Java left shift and right shift operators. Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-04-26 21:14 -0400
    Re: Java left shift and right shift operators. Travers Naran <tnaran@gmail.com> - 2011-04-26 07:30 -0700
      Re: Java left shift and right shift operators. Lew <noone@lewscanon.com> - 2011-04-26 11:24 -0400
        Re: Java left shift and right shift operators. Lew <noone@lewscanon.com> - 2011-04-26 11:35 -0400
          Re: Java left shift and right shift operators. Sanny <softtanks22@hotmail.com> - 2011-04-26 09:46 -0700
            Re: Java left shift and right shift operators. Lew <noone@lewscanon.com> - 2011-04-26 15:02 -0400
      Re: Java left shift and right shift operators. Lothar Kimmeringer <news200709@kimmeringer.de> - 2011-04-28 09:14 +0200
  Re: Java left shift and right shift operators. Joshua Cranmer <Pidgeot18@verizon.invalid> - 2011-04-26 08:41 -0400
  Re: Java left shift and right shift operators. Robert Klemme <shortcutter@googlemail.com> - 2011-04-26 22:06 +0200

csiph-web