-
Notifications
You must be signed in to change notification settings - Fork 0
/
ExceptionsPowLogTest.java
60 lines (52 loc) · 1.81 KB
/
ExceptionsPowLogTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package expression.exceptions;
import java.util.Arrays;
/**
* @author Georgiy Korneev ([email protected])
*/
public class ExceptionsPowLogTest extends ExceptionsTest {
public static final Reason POWER = new Reason("power");
public static final Reason LOG = new Reason("log");
protected ExceptionsPowLogTest() {
levels.add(list(
op("**", this::power),
op("//", this::log)
));
tests.addAll(Arrays.asList(
op("2 ** 3", (x, y, z) -> 8),
op("4 ** 3 ** 2", (x, y, z) -> 4096),
op("2 ** 3 * 3", (x, y, z) -> 24),
op("x ** (y * z)", (x, y, z) -> power(x, y * z)),
op("2 ** x + 1", (x, y, z) -> power(2, x) + 1),
op("-1 ** (3 ** x)", (x, y, z) -> x < 0 ? error(POWER) : -1),
op("8 // 2", (x, y, z) -> 3),
op("x // y", (x, y, z) -> log(x, y))
));
}
private long log(final long a, final long b) {
try {
final double result = Math.log(a) / Math.log(b);
return a > 0 && b > 0 && result == result ? (long) result : error(LOG);
} catch (final ArithmeticException e) {
return error(LOG);
}
}
private long power(final long a, long b) {
if (b < 0 || a == 0 && b == 0) {
return error(POWER);
}
if (Math.abs(a) <= 1 && b > 2) {
b = (b - 1) % 2 + 1;
}
double result = 1;
for (int i = 0; i < b; i++) {
result *= a;
if (result < Integer.MIN_VALUE || Integer.MAX_VALUE < result) {
return error(OVERFLOW);
}
}
return (long) result;
}
public static void main(final String[] args) {
new ExceptionsPowLogTest().run();
}
}