Home | History | Annotate | Download | only in Expressions
      1 /* The contents of this file are subject to the Netscape Public
      2  * License Version 1.1 (the "License"); you may not use this file
      3  * except in compliance with the License. You may obtain a copy of
      4  * the License at http://www.mozilla.org/NPL/
      5  *
      6  * Software distributed under the License is distributed on an "AS
      7  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
      8  * implied. See the License for the specific language governing
      9  * rights and limitations under the License.
     10  *
     11  * The Original Code is Mozilla Communicator client code, released March
     12  * 31, 1998.
     13  *
     14  * The Initial Developer of the Original Code is Netscape Communications
     15  * Corporation. Portions created by Netscape are
     16  * Copyright (C) 1998 Netscape Communications Corporation. All
     17  * Rights Reserved.
     18  *
     19  * Contributor(s):
     20  *
     21  */
     22 /**
     23     File Name:          11.7.2.js
     24     ECMA Section:       11.7.2  The signed right shift operator ( >> )
     25     Description:
     26     Performs a sign-filling bitwise right shift operation on the left argument
     27     by the amount specified by the right argument.
     28 
     29     The production ShiftExpression : ShiftExpression >> AdditiveExpression is
     30     evaluated as follows:
     31 
     32     1.  Evaluate ShiftExpression.
     33     2.  Call GetValue(Result(1)).
     34     3.  Evaluate AdditiveExpression.
     35     4.  Call GetValue(Result(3)).
     36     5.  Call ToInt32(Result(2)).
     37     6.  Call ToUint32(Result(4)).
     38     7.  Mask out all but the least significant 5 bits of Result(6), that is,
     39         compute Result(6) & 0x1F.
     40     8.  Perform sign-extending right shift of Result(5) by Result(7) bits. The
     41         most significant bit is propagated. The result is a signed 32 bit
     42         integer.
     43     9.  Return Result(8).
     44 
     45     Author:             christine (at) netscape.com
     46     Date:               12 november 1997
     47 */
     48     var SECTION = "11.7.2";
     49     var VERSION = "ECMA_1";
     50     startTest();
     51     var testcases = getTestCases();
     52 
     53     writeHeaderToLog( SECTION + "  The signed right shift operator ( >> )");
     54     test();
     55 
     56 function test() {
     57     for ( tc=0; tc < testcases.length; tc++ ) {
     58         testcases[tc].passed = writeTestCaseResult(
     59                             testcases[tc].expect,
     60                             testcases[tc].actual,
     61                             testcases[tc].description +" = "+
     62                             testcases[tc].actual );
     63 
     64         testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value ";
     65     }
     66     stopTest();
     67     return ( testcases );
     68 }
     69 function getTestCases() {
     70     var array = new Array();
     71     var item = 0;
     72     var power = 0;
     73     var addexp = 0;
     74 
     75     for ( power = 0; power <= 32; power++ ) {
     76         shiftexp = Math.pow( 2, power );
     77 
     78         for ( addexp = 0; addexp <= 32; addexp++ ) {
     79             array[item++] = new TestCase( SECTION,
     80                                     shiftexp + " >> " + addexp,
     81                                     SignedRightShift( shiftexp, addexp ),
     82                                     shiftexp >> addexp );
     83         }
     84     }
     85 
     86     for ( power = 0; power <= 32; power++ ) {
     87         shiftexp = -Math.pow( 2, power );
     88 
     89         for ( addexp = 0; addexp <= 32; addexp++ ) {
     90             array[item++] = new TestCase( SECTION,
     91                                     shiftexp + " >> " + addexp,
     92                                     SignedRightShift( shiftexp, addexp ),
     93                                     shiftexp >> addexp );
     94         }
     95     }
     96 
     97     return ( array );
     98 }
     99 
    100 function ToInteger( n ) {
    101     n = Number( n );
    102     var sign = ( n < 0 ) ? -1 : 1;
    103 
    104     if ( n != n ) {
    105         return 0;
    106     }
    107     if ( Math.abs( n ) == 0 || Math.abs( n ) == Number.POSITIVE_INFINITY ) {
    108         return n;
    109     }
    110     return ( sign * Math.floor(Math.abs(n)) );
    111 }
    112 function ToInt32( n ) {
    113     n = Number( n );
    114     var sign = ( n < 0 ) ? -1 : 1;
    115 
    116     if ( Math.abs( n ) == 0 || Math.abs( n ) == Number.POSITIVE_INFINITY) {
    117         return 0;
    118     }
    119 
    120     n = (sign * Math.floor( Math.abs(n) )) % Math.pow(2,32);
    121     n = ( n >= Math.pow(2,31) ) ? n - Math.pow(2,32) : n;
    122 
    123     return ( n );
    124 }
    125 function ToUint32( n ) {
    126     n = Number( n );
    127     var sign = ( n < 0 ) ? -1 : 1;
    128 
    129     if ( Math.abs( n ) == 0 || Math.abs( n ) == Number.POSITIVE_INFINITY) {
    130         return 0;
    131     }
    132     n = sign * Math.floor( Math.abs(n) )
    133 
    134     n = n % Math.pow(2,32);
    135 
    136     if ( n < 0 ){
    137         n += Math.pow(2,32);
    138     }
    139 
    140     return ( n );
    141 }
    142 function ToUint16( n ) {
    143     var sign = ( n < 0 ) ? -1 : 1;
    144 
    145     if ( Math.abs( n ) == 0 || Math.abs( n ) == Number.POSITIVE_INFINITY) {
    146         return 0;
    147     }
    148 
    149     n = ( sign * Math.floor( Math.abs(n) ) ) % Math.pow(2,16);
    150 
    151     if (n <0) {
    152         n += Math.pow(2,16);
    153     }
    154 
    155     return ( n );
    156 }
    157 function Mask( b, n ) {
    158     b = ToUint32BitString( b );
    159     b = b.substring( b.length - n );
    160     b = ToUint32Decimal( b );
    161     return ( b );
    162 }
    163 function ToUint32BitString( n ) {
    164     var b = "";
    165     for ( p = 31; p >=0; p-- ) {
    166         if ( n >= Math.pow(2,p) ) {
    167             b += "1";
    168             n -= Math.pow(2,p);
    169         } else {
    170             b += "0";
    171         }
    172     }
    173     return b;
    174 }
    175 function ToInt32BitString( n ) {
    176     var b = "";
    177     var sign = ( n < 0 ) ? -1 : 1;
    178 
    179     b += ( sign == 1 ) ? "0" : "1";
    180 
    181     for ( p = 30; p >=0; p-- ) {
    182         if ( (sign == 1 ) ? sign * n >= Math.pow(2,p) : sign * n > Math.pow(2,p) ) {
    183             b += ( sign == 1 ) ? "1" : "0";
    184             n -= sign * Math.pow( 2, p );
    185         } else {
    186             b += ( sign == 1 ) ? "0" : "1";
    187         }
    188     }
    189 
    190     return b;
    191 }
    192 function ToInt32Decimal( bin ) {
    193     var r = 0;
    194     var sign;
    195 
    196     if ( Number(bin.charAt(0)) == 0 ) {
    197         sign = 1;
    198         r = 0;
    199     } else {
    200         sign = -1;
    201         r = -(Math.pow(2,31));
    202     }
    203 
    204     for ( var j = 0; j < 31; j++ ) {
    205         r += Math.pow( 2, j ) * Number(bin.charAt(31-j));
    206     }
    207 
    208     return r;
    209 }
    210 function ToUint32Decimal( bin ) {
    211     var r = 0;
    212 
    213     for ( l = bin.length; l < 32; l++ ) {
    214         bin = "0" + bin;
    215     }
    216 
    217     for ( j = 0; j < 31; j++ ) {
    218         r += Math.pow( 2, j ) * Number(bin.charAt(31-j));
    219     }
    220 
    221     return r;
    222 }
    223 function SignedRightShift( s, a ) {
    224     s = ToInt32( s );
    225     a = ToUint32( a );
    226     a = Mask( a, 5 );
    227     return ( SignedRShift( s, a ) );
    228 }
    229 function SignedRShift( s, a ) {
    230     s = ToInt32BitString( s );
    231 
    232     var firstbit = s.substring(0,1);
    233 
    234     s = s.substring( 1, s.length );
    235 
    236     for ( var z = 0; z < a; z++ ) {
    237         s = firstbit + s;
    238     }
    239 
    240     s = s.substring( 0, s.length - a);
    241 
    242     s = firstbit +s;
    243 
    244 
    245     return ToInt32(ToInt32Decimal(s));
    246 }