+ if (result == PInfinity.d && x < 0.0 && isfinite (x) && ceil (y / 2) != floor (y / 2))
+ result = MInfinity.d;
+
+ /*
+ * The even/odd test in the if (this one and the one above) used to be ((long long) y % 2 == 0)
+ * on SPARC (long long) y for large y (>2**63) is always 0x7fffffff7fffffff, which
+ * is an odd number, so the test ((long long) y % 2 == 0) will always fail for
+ * large y. Since large double numbers are always even (e.g., the representation of
+ * 1E20+1 is the same as that of 1E20, the last .+1. is too insignificant to be part
+ * of the representation), this test will always return the wrong result for large y.
+ *
+ * The (ceil(y/2) == floor(y/2)) test is slower, but more robust.
+ */
+ if (result == MInfinity.d && x < 0.0 && isfinite (x) && ceil (y / 2) == floor (y / 2))
+ result = PInfinity.d;
+
+#if defined (__linux__) && SIZEOF_VOID_P == 4
+ /* On Linux 32bits, some tests erroneously return NaN */
+ if (isnan (result)) {
+ if (isminusone (x) && (y > 9007199254740991.0 || y < -9007199254740991.0)) {
+ /* Math.Pow (-1, Double.MaxValue) and Math.Pow (-1, Double.MinValue) should return 1 */
+ result = POne.d;
+ } else if (x < -9007199254740991.0 && y < -9007199254740991.0) {
+ /* Math.Pow (Double.MinValue, Double.MinValue) should return 0 */
+ result = 0.0;
+ } else if (x < -9007199254740991.0 && y > 9007199254740991.0) {
+ /* Math.Pow (Double.MinValue, Double.MaxValue) should return Double.PositiveInfinity */
+ result = PInfinity.d;
+ }