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 30var test_id = 0; 31function 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 53testRound(0, 0); 54testRound(-0, -0); 55testRound(Infinity, Infinity); 56testRound(-Infinity, -Infinity); 57testRound(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. 61function roundsum(i, n) { 62 var ret = Math.round(n); 63 while (--i > 0) { 64 ret += Math.round(n); 65 } 66 return ret; 67} 68assertEquals(-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). 72assertEquals(-0, roundsum(100000, -0)); 73 74testRound(1, 0.5); 75testRound(1, 0.7); 76testRound(1, 1); 77testRound(1, 1.1); 78testRound(1, 1.49999); 79testRound(-0, -0.5); 80testRound(-1, -0.5000000000000001); 81testRound(-1, -0.7); 82testRound(-1, -1); 83testRound(-1, -1.1); 84testRound(-1, -1.49999); 85testRound(-1, -1.5); 86 87testRound(9007199254740990, 9007199254740990); 88testRound(9007199254740991, 9007199254740991); 89testRound(-9007199254740990, -9007199254740990); 90testRound(-9007199254740991, -9007199254740991); 91testRound(Number.MAX_VALUE, Number.MAX_VALUE); 92testRound(-Number.MAX_VALUE, -Number.MAX_VALUE); 93testRound(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER); 94testRound(Number.MAX_SAFE_INTEGER + 1, Number.MAX_SAFE_INTEGER + 1); 95testRound(Number.MAX_SAFE_INTEGER + 2, Number.MAX_SAFE_INTEGER + 2); 96testRound(Number.MAX_SAFE_INTEGER + 3, Number.MAX_SAFE_INTEGER + 3); 97testRound(Number.MAX_SAFE_INTEGER + 4, Number.MAX_SAFE_INTEGER + 4); 98testRound(Number.MIN_SAFE_INTEGER, Number.MIN_SAFE_INTEGER); 99testRound(Number.MIN_SAFE_INTEGER - 1, Number.MIN_SAFE_INTEGER - 1); 100testRound(Number.MIN_SAFE_INTEGER - 2, Number.MIN_SAFE_INTEGER - 2); 101testRound(Number.MIN_SAFE_INTEGER - 3, Number.MIN_SAFE_INTEGER - 3); 102 103testRound(536870911, 536870910.5); 104testRound(536870911, 536870911); 105testRound(536870911, 536870911.4); 106testRound(536870912, 536870911.5); 107testRound(536870912, 536870912); 108testRound(536870912, 536870912.4); 109testRound(536870913, 536870912.5); 110testRound(536870913, 536870913); 111testRound(536870913, 536870913.4); 112testRound(1073741823, 1073741822.5); 113testRound(1073741823, 1073741823); 114testRound(1073741823, 1073741823.4); 115testRound(1073741824, 1073741823.5); 116testRound(1073741824, 1073741824); 117testRound(1073741824, 1073741824.4); 118testRound(1073741825, 1073741824.5); 119testRound(2147483647, 2147483646.5); 120testRound(2147483647, 2147483647); 121testRound(2147483647, 2147483647.4); 122testRound(2147483648, 2147483647.5); 123testRound(2147483648, 2147483648); 124testRound(2147483648, 2147483648.4); 125testRound(2147483649, 2147483648.5); 126 127// Tests based on WebKit LayoutTests 128 129testRound(0, 0.4); 130testRound(-0, -0.4); 131testRound(-0, -0.5); 132testRound(1, 0.6); 133testRound(-1, -0.6); 134testRound(2, 1.5); 135testRound(2, 1.6); 136testRound(-2, -1.6); 137testRound(8640000000000000, 8640000000000000); 138testRound(8640000000000001, 8640000000000001); 139testRound(8640000000000002, 8640000000000002); 140testRound(9007199254740990, 9007199254740990); 141testRound(9007199254740991, 9007199254740991); 142testRound(1.7976931348623157e+308, 1.7976931348623157e+308); 143testRound(-8640000000000000, -8640000000000000); 144testRound(-8640000000000001, -8640000000000001); 145testRound(-8640000000000002, -8640000000000002); 146testRound(-9007199254740990, -9007199254740990); 147testRound(-9007199254740991, -9007199254740991); 148testRound(-1.7976931348623157e+308, -1.7976931348623157e+308); 149testRound(Infinity, Infinity); 150testRound(-Infinity, -Infinity); 151 152 // Some special double number cases. 153var ulp = Math.pow(2, -1022 - 52); 154var max_denormal = (Math.pow(2, 52) - 1) * ulp; 155var min_normal = Math.pow(2, -1022); 156var max_fraction = Math.pow(2, 52) - 0.5; 157var min_nonfraction = Math.pow(2, 52); 158var max_non_infinite = Number.MAX_VALUE; 159 160var max_smi31 = Math.pow(2,30) - 1; 161var min_smi31 = -Math.pow(2,30); 162var max_smi32 = Math.pow(2,31) - 1; 163var min_smi32 = -Math.pow(2,31); 164 165testRound(0, ulp); 166testRound(0, max_denormal); 167testRound(0, min_normal); 168testRound(0, 0.49999999999999994); 169testRound(1, 0.5); 170testRound(Math.pow(2,52), max_fraction); 171testRound(min_nonfraction, min_nonfraction); 172testRound(max_non_infinite, max_non_infinite); 173 174testRound(max_smi31, max_smi31 - 0.5); 175testRound(max_smi31 + 1, max_smi31 + 0.5); 176testRound(max_smi32, max_smi32 - 0.5); 177testRound(max_smi32 + 1, max_smi32 + 0.5); 178 179testRound(-0, -ulp); 180testRound(-0, -max_denormal); 181testRound(-0, -min_normal); 182testRound(-0, -0.49999999999999994); 183testRound(-0, -0.5); 184testRound(-Math.pow(2,52)+1, -max_fraction); 185testRound(-min_nonfraction, -min_nonfraction); 186testRound(-max_non_infinite, -max_non_infinite); 187 188testRound(min_smi31, min_smi31 - 0.5); 189testRound(min_smi31 + 1, min_smi31 + 0.5); 190testRound(min_smi32, min_smi32 - 0.5); 191testRound(min_smi32 + 1, min_smi32 + 0.5); 192