// Copyright (c) 2019, 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.

// Extreme values from int_modulo_arith_test. Test cases that that have
// intermediate values that overflow the precision of 'int'.

import "package:expect/expect.dart";

import "dart:math" show pow;

main() {
  test(x, e, m, expectedResult) {
    var result = x.modPow(e, m);
    Expect.equals(expectedResult, result, "$x.modPow($e, $m)");
  }

  for (int mBase in [
    50000000,
    94906266, // Smallest integer with square over 2^53.
    100000000,
    1000000000,
    3037000500, // Smallest integer with square over 2^63.
    4000000000,
    0x7FFFFFFFFFFFF000 + 0xFFC
  ]) {
    // On 'web' platforms skip values outside web number safe range.
    if (mBase == mBase + 1) continue;

    for (int mAdjustment in [0, 1, 2, 3, -1]) {
      int m = mBase + mAdjustment;
      for (int e = 1; e < 100; e++) {
        // Test "M-k ^ N mod M == (-k) ^ N mod M" for some small values of k.
        test(m - 1, e, m, pow(-1, e) % m);
        if (e < 53) {
          test(m - 2, e, m, pow(-2, e) % m);
        }
        if (e < 33) {
          test(m - 3, e, m, pow(-3, e) % m);
        }
        if (e < 26) {
          test(m - 4, e, m, pow(-4, e) % m);
        }
      }
    }
  }
}

Test for overflow in int.modPow()
[corelib] Test for overflow in int.modPow()

Bug: 37469
Change-Id: If7a6cc1063ddfdab1c5a0261a7b0c5d168c081b7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/109316
Reviewed-by: Lasse R.H. Nielsen <80295e4ef244a07779f93eaa95d582bad8e316a5@google.com>
Commit-Queue: Stephen Adams <60cb5b73b7e0cb7dcda53302da4fab6ecfc7fa8b@google.com>
