Index: test/mjsunit/math-exp-precision.js |
diff --git a/test/mjsunit/regress/regress-transcendental.js b/test/mjsunit/math-exp-precision.js |
similarity index 58% |
copy from test/mjsunit/regress/regress-transcendental.js |
copy to test/mjsunit/math-exp-precision.js |
index b5dbcb48af6345226819b6c0d29d93ef2e71c702..7d802079f04e57506bee8764466e9931ff1d8ceb 100644 |
--- a/test/mjsunit/regress/regress-transcendental.js |
+++ b/test/mjsunit/math-exp-precision.js |
@@ -25,25 +25,40 @@ |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
-// Flags: --expose-gc |
+// Tests that the --fast-math implementation of Math.exp() has |
+// reasonable precision. |
-// Test whether the runtime implementation and generated code of |
-// sine and tangens return the same results. |
+function exp(x) { |
+ return Math.exp(x); |
+} |
+ |
+var first_call_result = exp(Math.PI); |
+var second_call_result = exp(Math.PI); |
-function test(f, x, name) { |
- // Reset transcendental cache. |
- gc(); |
- // Initializing cache leads to a runtime call. |
- var runtime_result = f(x); |
- // Flush transcendental cache entries and optimize f. |
- for (var i = 0; i < 100000; i++) f(i); |
- // Calculate using generated code. |
- var gencode_result = f(x); |
- print(name + " runtime function: " + runtime_result); |
- print(name + " generated code : " + gencode_result); |
- assertEquals(gencode_result, runtime_result); |
+function assertAlmostEquals(expected, actual, x) { |
+ if (expected == 0 && actual == 0) return; // OK |
+ if (expected == Number.POSITIVE_INFINITY && |
+ actual == Number.POSITIVE_INFINITY) { |
+ return; // OK |
+ } |
+ relative_diff = Math.abs(expected/actual - 1); |
+ assertTrue(relative_diff < 1e-12, "relative difference of " + relative_diff + |
+ " for input " + x); |
} |
-test(Math.tan, -1.57079632679489660000, "Math.tan"); |
-test(Math.sin, 6.283185307179586, "Math.sin"); |
+var increment = Math.PI / 35; // Roughly 0.1, but we want to try many |
+ // different mantissas. |
+for (var x = -708; x < 710; x += increment) { |
+ var ex = exp(x); |
+ var reference = Math.pow(Math.E, x); |
+ assertAlmostEquals(reference, ex, x); |
+ if (ex > 0 && isFinite(ex)) { |
+ var back = Math.log(ex); |
+ assertAlmostEquals(x, back, x + " (backwards)"); |
+ } |
+} |
+// Make sure optimizing the function does not alter the result. |
+var last_call_result = exp(Math.PI); |
+assertEquals(first_call_result, second_call_result); |
+assertEquals(first_call_result, last_call_result); |