// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// VMOptions=--optimization-counter-threshold=5 --no-background-compilation

// @dart = 2.9

library math_test;

import "package:expect/expect.dart";
import 'dart:math';

void checkVeryClose(double a, double b) {
  // We find a ulp (unit in the last place) by shifting the original number
  // to the right. This only works if we are not too close to infinity or if
  // we work with denormals.
  // We special case for 0.0, but not for infinity.
  if (a == 0.0) {
    final minimalDouble = 4.9406564584124654e-324;
    Expect.equals(true, b.abs() <= minimalDouble);
    return;
  }
  if (b == 0.0) {
    // No need to look if they are close. Otherwise the check for 'a' above
    // would have triggered.
    Expect.equals(a, b);
  }
  final double shiftRightBy52 = 2.220446049250313080847263336181640625e-16;
  final double shiftedA = (a * shiftRightBy52).abs();
  // Compared to 'a', 'shiftedA' is now ~1-2 ulp.

  final double limitLow = a - shiftedA;
  final double limitHigh = a + shiftedA;
  Expect.equals(false, a == limitLow);
  Expect.equals(false, a == limitHigh);
  Expect.equals(true, limitLow <= b);
  Expect.equals(true, b <= limitHigh);
}

const NaN = double.nan;
const Infinity = double.infinity;

var samples = [
  NaN,
  -Infinity,
  -3.0, // Odd integer
  -2.0, // Even integer
  -1.5, // Non-integer, magnitude > 1
  -1.0, // Unit
  -0.5, // Non-integer, magnitude < 1.
  -0.0,
  0.5, // Non-integer, magnitude < 1.
  1.0, // Unit
  1.5, // Non-integer, magnitude > 1
  2.0, // Even integer
  3.0, // Odd integer
  Infinity
];

test() {
  // Tests of pow(x, y):
  for (var d in samples) {
    // if `y` is zero (0.0 or -0.0), the result is always 1.0.
    Expect.identical(1.0, pow(d, 0.0), "$d");
    Expect.identical(1.0, pow(d, -0.0), "$d");
  }
  for (var d in samples) {
    // if `x` is 1.0, the result is always 1.0.
    Expect.identical(1.0, pow(1.0, d), "$d");
  }
  for (var d in samples) {
    // otherwise, if either `x` or `y` is NaN then the result is NaN.
    if (d != 0.0) Expect.isTrue(pow(NaN, d).isNaN, "$d");
    if (d != 1.0) Expect.isTrue(pow(d, NaN).isNaN, "$d");
  }

  for (var d in samples) {
    // if `x` is a finite and strictly negative and `y` is a finite non-integer,
    // the result is NaN.
    if (d < 0 && !d.isInfinite) {
      Expect.isTrue(pow(d, 0.5).isNaN, "$d");
      Expect.isTrue(pow(d, -0.5).isNaN, "$d");
      Expect.isTrue(pow(d, 1.5).isNaN, "$d");
      Expect.isTrue(pow(d, -1.5).isNaN, "$d");
    }
  }

  for (var d in samples) {
    if (d < 0) {
      // if `x` is Infinity and `y` is strictly negative, the result is 0.0.
      Expect.identical(0.0, pow(Infinity, d), "$d");
    }
    if (d > 0) {
      // if `x` is Infinity and `y` is strictly positive, the result is Infinity.
      Expect.identical(Infinity, pow(Infinity, d), "$d");
    }
  }

  for (var d in samples) {
    if (d < 0) {
      // if `x` is 0.0 and `y` is strictly negative, the result is Infinity.
      Expect.identical(Infinity, pow(0.0, d), "$d");
    }
    if (d > 0) {
      // if `x` is 0.0 and `y` is strictly positive, the result is 0.0.
      Expect.identical(0.0, pow(0.0, d), "$d");
    }
  }

  for (var d in samples) {
    if (!d.isInfinite && !d.isNaN) {
      var dint = d.toInt();
      if (d == dint && dint.isOdd) {
        // if `x` is -Infinity or -0.0 and `y` is an odd integer, then the
        // result is`-pow(-x ,y)`.
        Expect.identical(-pow(Infinity, d), pow(-Infinity, d));
        Expect.identical(-pow(0.0, d), pow(-0.0, d));
        continue;
      }
    }
    // if `x` is -Infinity or -0.0 and `y` is not an odd integer, then the
    // result is the same as `pow(-x , y)`.
    if (d.isNaN) {
      Expect.isTrue(pow(Infinity, d).isNaN);
      Expect.isTrue(pow(-Infinity, d).isNaN);
      Expect.isTrue(pow(0.0, d).isNaN);
      Expect.isTrue(pow(-0.0, d).isNaN);
      continue;
    }
    Expect.identical(pow(Infinity, d), pow(-Infinity, d));
    Expect.identical(pow(0.0, d), pow(-0.0, d));
  }

  for (var d in samples) {
    if (d.abs() < 1) {
      // if `y` is Infinity and the absolute value of `x` is less than 1, the
      // result is 0.0.
      Expect.identical(0.0, pow(d, Infinity));
    } else if (d.abs() > 1) {
      // if `y` is Infinity and the absolute value of `x` is greater than 1,
      // the result is Infinity.
      Expect.identical(Infinity, pow(d, Infinity));
    } else if (d == -1) {
      // if `y` is Infinity and `x` is -1, the result is 1.0.
      Expect.identical(1.0, pow(d, Infinity));
    }
    // if `y` is -Infinity, the result is `1/pow(x, Infinity)`.
    if (d.isNaN) {
      Expect.isTrue((1 / pow(d, Infinity)).isNaN);
      Expect.isTrue(pow(d, -Infinity).isNaN);
    } else {
      Expect.identical(1 / pow(d, Infinity), pow(d, -Infinity));
    }
  }

  // Some non-exceptional values.
  checkVeryClose(16.0, pow(4.0, 2.0));
  checkVeryClose(sqrt2, pow(2.0, 0.5));
  checkVeryClose(sqrt1_2, pow(0.5, 0.5));
  // Denormal result.
  Expect.identical(5e-324, pow(2.0, -1074.0));
  // Overflow.
  Expect.identical(Infinity, pow(10.0, 309.0));
  // Underflow.
  Expect.identical(0.0, pow(10.0, -325.0));

  // Conversion to double.

  // The second argument is an odd integer as int, but not when converted
  // to double.
  Expect.identical(Infinity, pow(-0.0, -9223372036854775807));
}

main() {
  for (int i = 0; i < 10; i++) test();
}
