// 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. // VMOptions=--deterministic // VMOptions=--deterministic --use_slow_path // Unit tests on DIV and MOV operations by various constants. import "package:expect/expect.dart"; import 'dart:core'; int kMin = 0x8000000000000000; int kMax = 0x7fffffffffffffff; // The basic DIV operation. int divme(int? x, int c) { return x! ~/ c; } // The basic MOD operation. int modme(int? x, int c) { return x! % c; } // // Test several "hidden" DIV constants. // @pragma("vm:never-inline") int div0(int x) { return divme(x, 0); } @pragma("vm:never-inline") int div1(int x) { return divme(x, 1); } @pragma("vm:never-inline") int divm1(int x) { return divme(x, -1); } @pragma("vm:never-inline") int div2(int? x) { return divme(x, 2); } @pragma("vm:never-inline") int divm2(int x) { return divme(x, -2); } @pragma("vm:never-inline") int div37(int x) { return divme(x, 37); } @pragma("vm:never-inline") int div131(int x) { return divme(x, 131); } @pragma("vm:never-inline") int divm333(int x) { return divme(x, -333); } @pragma("vm:never-inline") int divmin(int x) { return divme(x, kMin); } @pragma("vm:never-inline") int divmax(int x) { return divme(x, kMax); } // // Test several "hidden" MOD constants. // @pragma("vm:never-inline") int mod0(int x) { return modme(x, 0); } @pragma("vm:never-inline") int mod1(int x) { return modme(x, 1); } @pragma("vm:never-inline") int modm1(int x) { return modme(x, -1); } @pragma("vm:never-inline") int mod2(int? x) { return modme(x, 2); } @pragma("vm:never-inline") int modm2(int x) { return modme(x, -2); } @pragma("vm:never-inline") int mod37(int x) { return modme(x, 37); } @pragma("vm:never-inline") int mod131(int x) { return modme(x, 131); } @pragma("vm:never-inline") int modm333(int x) { return modme(x, -333); } @pragma("vm:never-inline") int modmin(int x) { return modme(x, kMin); } @pragma("vm:never-inline") int modmax(int x) { return modme(x, kMax); } main() { // Exceptional case DIV. for (int i = -1; i <= 1; i++) { bool threw = false; try { div0(i); } on IntegerDivisionByZeroException catch (e) { threw = true; } Expect.isTrue(threw); } // Exceptional case MOD. for (int i = -1; i <= 1; i++) { bool threw = false; try { mod0(i); } on IntegerDivisionByZeroException catch (e) { threw = true; } Expect.isTrue(threw); } // DIV by +/- 1. Expect.equals(kMin, div1(kMin)); Expect.equals(kMin, divm1(kMin)); for (int i = -999; i <= 999; i++) { Expect.equals(i, div1(i)); Expect.equals(-i, divm1(i)); } Expect.equals(kMax, div1(kMax)); Expect.equals(-kMax, divm1(kMax)); // MOD by +/- 1. Expect.equals(0, mod1(kMin)); Expect.equals(0, modm1(kMin)); for (int i = -999; i <= 999; i++) { Expect.equals(0, mod1(i)); Expect.equals(0, modm1(i)); } Expect.equals(0, mod1(kMax)); Expect.equals(0, modm1(kMax)); // DIV by +/- 2. Expect.equals(-4611686018427387904, div2(kMin)); Expect.equals(-4611686018427387903, div2(kMin + 1)); Expect.equals(-4611686018427387903, div2(kMin + 2)); Expect.equals(4611686018427387904, divm2(kMin)); Expect.equals(4611686018427387903, divm2(kMin + 1)); Expect.equals(4611686018427387903, divm2(kMin + 2)); for (int i = -999; i <= 999; i++) { int e = (i + ((i < 0) ? 1 : 0)) >> 1; Expect.equals(e, div2(i)); Expect.equals(-e, divm2(i)); } Expect.equals(4611686018427387903, div2(kMax)); Expect.equals(4611686018427387903, div2(kMax - 1)); Expect.equals(4611686018427387902, div2(kMax - 2)); Expect.equals(-4611686018427387903, divm2(kMax)); Expect.equals(-4611686018427387903, divm2(kMax - 1)); Expect.equals(-4611686018427387902, divm2(kMax - 2)); // MOD by +/- 2. Expect.equals(0, mod2(kMin)); Expect.equals(1, mod2(kMin + 1)); Expect.equals(0, mod2(kMin + 2)); Expect.equals(0, modm2(kMin)); Expect.equals(1, modm2(kMin + 1)); Expect.equals(0, modm2(kMin + 2)); for (int i = -999; i <= 999; i++) { Expect.equals(i & 1, mod2(i)); Expect.equals(i & 1, modm2(i)); } Expect.equals(1, mod2(kMax)); Expect.equals(0, mod2(kMax - 1)); Expect.equals(1, mod2(kMax - 2)); Expect.equals(1, modm2(kMax)); Expect.equals(0, modm2(kMax - 1)); Expect.equals(1, modm2(kMax - 2)); // DIV/MOD by 37. Expect.equals(-249280325320399346, div37(kMin)); Expect.equals(31, mod37(kMin)); for (int i = -999; i <= 999; i++) { Expect.equals(i, div37(37 * i)); Expect.equals(i, div37(37 * i + ((i >= 0) ? 36 : -36))); Expect.equals(0, mod37(37 * i)); Expect.equals(1, mod37(37 * i + 1)); Expect.equals(36, mod37(37 * i + 36)); } for (int i = 1; i < 37; i++) { Expect.equals(0, div37(i)); Expect.equals(i, mod37(i)); Expect.equals(0, div37(-i)); Expect.equals(37 - i, mod37(-i)); } Expect.equals(249280325320399346, div37(kMax)); Expect.equals(5, mod37(kMax)); // DIV/MOD by 131. Expect.equals(-70407420128662410, div131(kMin)); Expect.equals(33, mod131(kMin)); for (int i = -999; i <= 999; i++) { Expect.equals(i, div131(131 * i)); Expect.equals(i, div131(131 * i + ((i >= 0) ? 130 : -130))); Expect.equals(0, mod131(131 * i)); Expect.equals(1, mod131(131 * i + 1)); Expect.equals(130, mod131(131 * i + 130)); } for (int i = 1; i < 131; i++) { Expect.equals(0, div131(i)); Expect.equals(i, mod131(i)); Expect.equals(0, div131(-i)); Expect.equals(131 - i, mod131(-i)); } Expect.equals(70407420128662410, div131(kMax)); Expect.equals(97, mod131(kMax)); // DIV/MOD by -333. Expect.equals(27697813924488816, divm333(kMin)); Expect.equals(253, modm333(kMin)); for (int i = -999; i <= 999; i++) { Expect.equals(i, divm333(-333 * i)); Expect.equals(i, divm333(-333 * i + ((i < 0) ? 130 : -130))); Expect.equals(0, modm333(-333 * i)); Expect.equals(1, modm333(-333 * i + 1)); Expect.equals(130, modm333(-333 * i + 130)); } Expect.equals(-27697813924488816, divm333(kMax)); Expect.equals(79, modm333(kMax)); // DIV/MOD by Min. Expect.equals(1, divmin(kMin)); Expect.equals(0, modmin(kMin)); for (int i = -999; i <= 999; i++) { Expect.equals(0, divmin(i)); Expect.equals(i >= 0 ? i : 1 + kMax + i, modmin(i)); } Expect.equals(0, divmin(kMax)); Expect.equals(kMax, modmin(kMax)); // DIV/MOD by Max. Expect.equals(-1, divmax(kMin)); Expect.equals(kMax - 1, modmax(kMin)); for (int i = -999; i <= 999; i++) { Expect.equals(0, divmax(i)); Expect.equals(i >= 0 ? i : kMax + i, modmax(i)); } Expect.equals(1, divmax(kMax)); Expect.equals(0, modmax(kMax)); // Exceptional null value MOD. bool threwDiv = false; try { div2(null); } on TypeError catch (e) { threwDiv = true; } Expect.isTrue(threwDiv); // Exceptional null value MOD. bool threwMod = false; try { mod2(null); } on TypeError catch (e) { threwMod = true; } Expect.isTrue(threwMod); }