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 }