1 // Copyright 2011 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 // Flags: --allow-natives-syntax 29 30 var test_id = 0; 31 function testRound(expect, input) { 32 // Make source code different on each invocation to make 33 // sure it gets optimized each time. 34 var doRound = new Function('input', 35 '"' + (test_id++) + '";return Math.round(input)'); 36 assertEquals(expect, doRound(input)); 37 assertEquals(expect, doRound(input)); 38 assertEquals(expect, doRound(input)); 39 %OptimizeFunctionOnNextCall(doRound); 40 assertEquals(expect, doRound(input)); 41 42 // Force the Math.round() representation to double to exercise the associated 43 // optimized code. 44 var doRoundToDouble = new Function('input', 45 '"' + (test_id++) + '";return Math.round(input) + -0.0'); 46 assertEquals(expect, doRoundToDouble(input)); 47 assertEquals(expect, doRoundToDouble(input)); 48 assertEquals(expect, doRoundToDouble(input)); 49 %OptimizeFunctionOnNextCall(doRoundToDouble); 50 assertEquals(expect, doRoundToDouble(input)); 51 } 52 53 testRound(0, 0); 54 testRound(-0, -0); 55 testRound(Infinity, Infinity); 56 testRound(-Infinity, -Infinity); 57 testRound(NaN, NaN); 58 59 // Regression test for a bug where a negative zero coming from Math.round 60 // was not properly handled by other operations. 61 function roundsum(i, n) { 62 var ret = Math.round(n); 63 while (--i > 0) { 64 ret += Math.round(n); 65 } 66 return ret; 67 } 68 assertEquals(-0, roundsum(1, -0)); 69 %OptimizeFunctionOnNextCall(roundsum); 70 // The optimized function will deopt. Run it with enough iterations to try 71 // to optimize via OSR (triggering the bug). 72 assertEquals(-0, roundsum(100000, -0)); 73 74 testRound(1, 0.5); 75 testRound(1, 0.7); 76 testRound(1, 1); 77 testRound(1, 1.1); 78 testRound(1, 1.49999); 79 testRound(-0, -0.5); 80 testRound(-1, -0.5000000000000001); 81 testRound(-1, -0.7); 82 testRound(-1, -1); 83 testRound(-1, -1.1); 84 testRound(-1, -1.49999); 85 testRound(-1, -1.5); 86 87 testRound(9007199254740990, 9007199254740990); 88 testRound(9007199254740991, 9007199254740991); 89 testRound(-9007199254740990, -9007199254740990); 90 testRound(-9007199254740991, -9007199254740991); 91 testRound(Number.MAX_VALUE, Number.MAX_VALUE); 92 testRound(-Number.MAX_VALUE, -Number.MAX_VALUE); 93 testRound(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER); 94 testRound(Number.MAX_SAFE_INTEGER + 1, Number.MAX_SAFE_INTEGER + 1); 95 testRound(Number.MAX_SAFE_INTEGER + 2, Number.MAX_SAFE_INTEGER + 2); 96 testRound(Number.MAX_SAFE_INTEGER + 3, Number.MAX_SAFE_INTEGER + 3); 97 testRound(Number.MAX_SAFE_INTEGER + 4, Number.MAX_SAFE_INTEGER + 4); 98 testRound(Number.MIN_SAFE_INTEGER, Number.MIN_SAFE_INTEGER); 99 testRound(Number.MIN_SAFE_INTEGER - 1, Number.MIN_SAFE_INTEGER - 1); 100 testRound(Number.MIN_SAFE_INTEGER - 2, Number.MIN_SAFE_INTEGER - 2); 101 testRound(Number.MIN_SAFE_INTEGER - 3, Number.MIN_SAFE_INTEGER - 3); 102 103 testRound(536870911, 536870910.5); 104 testRound(536870911, 536870911); 105 testRound(536870911, 536870911.4); 106 testRound(536870912, 536870911.5); 107 testRound(536870912, 536870912); 108 testRound(536870912, 536870912.4); 109 testRound(536870913, 536870912.5); 110 testRound(536870913, 536870913); 111 testRound(536870913, 536870913.4); 112 testRound(1073741823, 1073741822.5); 113 testRound(1073741823, 1073741823); 114 testRound(1073741823, 1073741823.4); 115 testRound(1073741824, 1073741823.5); 116 testRound(1073741824, 1073741824); 117 testRound(1073741824, 1073741824.4); 118 testRound(1073741825, 1073741824.5); 119 testRound(2147483647, 2147483646.5); 120 testRound(2147483647, 2147483647); 121 testRound(2147483647, 2147483647.4); 122 testRound(2147483648, 2147483647.5); 123 testRound(2147483648, 2147483648); 124 testRound(2147483648, 2147483648.4); 125 testRound(2147483649, 2147483648.5); 126 127 // Tests based on WebKit LayoutTests 128 129 testRound(0, 0.4); 130 testRound(-0, -0.4); 131 testRound(-0, -0.5); 132 testRound(1, 0.6); 133 testRound(-1, -0.6); 134 testRound(2, 1.5); 135 testRound(2, 1.6); 136 testRound(-2, -1.6); 137 testRound(8640000000000000, 8640000000000000); 138 testRound(8640000000000001, 8640000000000001); 139 testRound(8640000000000002, 8640000000000002); 140 testRound(9007199254740990, 9007199254740990); 141 testRound(9007199254740991, 9007199254740991); 142 testRound(1.7976931348623157e+308, 1.7976931348623157e+308); 143 testRound(-8640000000000000, -8640000000000000); 144 testRound(-8640000000000001, -8640000000000001); 145 testRound(-8640000000000002, -8640000000000002); 146 testRound(-9007199254740990, -9007199254740990); 147 testRound(-9007199254740991, -9007199254740991); 148 testRound(-1.7976931348623157e+308, -1.7976931348623157e+308); 149 testRound(Infinity, Infinity); 150 testRound(-Infinity, -Infinity); 151 152 // Some special double number cases. 153 var ulp = Math.pow(2, -1022 - 52); 154 var max_denormal = (Math.pow(2, 52) - 1) * ulp; 155 var min_normal = Math.pow(2, -1022); 156 var max_fraction = Math.pow(2, 52) - 0.5; 157 var min_nonfraction = Math.pow(2, 52); 158 var max_non_infinite = Number.MAX_VALUE; 159 160 var max_smi31 = Math.pow(2,30) - 1; 161 var min_smi31 = -Math.pow(2,30); 162 var max_smi32 = Math.pow(2,31) - 1; 163 var min_smi32 = -Math.pow(2,31); 164 165 testRound(0, ulp); 166 testRound(0, max_denormal); 167 testRound(0, min_normal); 168 testRound(0, 0.49999999999999994); 169 testRound(1, 0.5); 170 testRound(Math.pow(2,52), max_fraction); 171 testRound(min_nonfraction, min_nonfraction); 172 testRound(max_non_infinite, max_non_infinite); 173 174 testRound(max_smi31, max_smi31 - 0.5); 175 testRound(max_smi31 + 1, max_smi31 + 0.5); 176 testRound(max_smi32, max_smi32 - 0.5); 177 testRound(max_smi32 + 1, max_smi32 + 0.5); 178 179 testRound(-0, -ulp); 180 testRound(-0, -max_denormal); 181 testRound(-0, -min_normal); 182 testRound(-0, -0.49999999999999994); 183 testRound(-0, -0.5); 184 testRound(-Math.pow(2,52)+1, -max_fraction); 185 testRound(-min_nonfraction, -min_nonfraction); 186 testRound(-max_non_infinite, -max_non_infinite); 187 188 testRound(min_smi31, min_smi31 - 0.5); 189 testRound(min_smi31 + 1, min_smi31 + 0.5); 190 testRound(min_smi32, min_smi32 - 0.5); 191 testRound(min_smi32 + 1, min_smi32 + 0.5); 192