Implement checked exponentiation.

This commit is contained in:
chriseth
2020-08-18 12:42:53 +02:00
parent 660ef792ab
commit c34e349572
9 changed files with 325 additions and 2 deletions
@@ -10,5 +10,7 @@ contract test {
return (x**y1, x**y2);
}
}
// ====
// compileViaYul: also
// ----
// f() -> 9, -27
@@ -0,0 +1,19 @@
contract C {
function f(uint x, uint y) public returns (uint) {
return x**y;
}
}
// ====
// compileViaYul: also
// ----
// f(uint256,uint256): 0, 0 -> 1
// f(uint256,uint256): 0, 1 -> 0x00
// f(uint256,uint256): 0, 2 -> 0x00
// f(uint256,uint256): 1, 0 -> 1
// f(uint256,uint256): 1, 1 -> 1
// f(uint256,uint256): 1, 2 -> 1
// f(uint256,uint256): 2, 0 -> 1
// f(uint256,uint256): 2, 1 -> 2
// f(uint256,uint256): 2, 2 -> 4
// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343
// f(uint256,uint256): 128, 2 -> 0x4000
@@ -0,0 +1,28 @@
contract C {
function f(int x, uint y) public returns (int) {
return x**y;
}
}
// ====
// compileViaYul: also
// ----
// f(int256,uint256): 0, 0 -> 1
// f(int256,uint256): 0, 1 -> 0x00
// f(int256,uint256): 0, 2 -> 0x00
// f(int256,uint256): 1, 0 -> 1
// f(int256,uint256): 1, 1 -> 1
// f(int256,uint256): 1, 2 -> 1
// f(int256,uint256): 2, 0 -> 1
// f(int256,uint256): 2, 1 -> 2
// f(int256,uint256): 2, 2 -> 4
// f(int256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343
// f(int256,uint256): 128, 2 -> 0x4000
// f(int256,uint256): -1, 0 -> 1
// f(int256,uint256): -1, 1 -> -1
// f(int256,uint256): -1, 2 -> 1
// f(int256,uint256): -2, 0 -> 1
// f(int256,uint256): -2, 1 -> -2
// f(int256,uint256): -2, 2 -> 4
// f(int256,uint256): -7, 63 -> -174251498233690814305510551794710260107945042018748343
// f(int256,uint256): -128, 2 -> 0x4000
// f(int256,uint256): -1, 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> -1
@@ -0,0 +1,38 @@
contract C {
function f(int8 x, uint y) public returns (int) {
return x**y;
}
function g(int256 x, uint y) public returns (int) {
return x**y;
}
}
// ====
// compileViaYul: true
// ----
// f(int8,uint256): 2, 6 -> 64
// f(int8,uint256): 2, 7 -> FAILURE
// f(int8,uint256): 2, 8 -> FAILURE
// f(int8,uint256): -2, 6 -> 64
// f(int8,uint256): -2, 7 -> -128
// f(int8,uint256): -2, 8 -> FAILURE
// f(int8,uint256): 6, 3 -> FAILURE
// f(int8,uint256): 7, 2 -> 0x31
// f(int8,uint256): 7, 3 -> FAILURE
// f(int8,uint256): -7, 2 -> 0x31
// f(int8,uint256): -7, 3 -> FAILURE
// f(int8,uint256): -7, 4 -> FAILURE
// f(int8,uint256): 127, 31 -> FAILURE
// f(int8,uint256): 127, 131 -> FAILURE
// f(int8,uint256): -128, 0 -> 1
// f(int8,uint256): -128, 1 -> -128
// f(int8,uint256): -128, 31 -> FAILURE
// f(int8,uint256): -128, 131 -> FAILURE
// f(int8,uint256): -11, 2 -> 121
// f(int8,uint256): -12, 2 -> FAILURE
// f(int8,uint256): 12, 2 -> FAILURE
// f(int8,uint256): -5, 3 -> -125
// f(int8,uint256): -6, 3 -> FAILURE
// g(int256,uint256): -7, 90 -> 11450477594321044359340126713545146077054004823284978858214566372120240027249
// g(int256,uint256): -7, 91 -> FAILURE
// g(int256,uint256): -63, 42 -> 3735107253208426854890677539053540390278853997836851167913009474475553834369
// g(int256,uint256): -63, 43 -> FAILURE
@@ -0,0 +1,31 @@
contract C {
function f(uint8 x, uint8 y) public returns (uint) {
return x**y;
}
function g(uint x, uint y) public returns (uint) {
return x**y;
}
}
// ====
// compileViaYul: true
// ----
// f(uint8,uint8): 2, 7 -> 0x80
// f(uint8,uint8): 2, 8 -> FAILURE
// f(uint8,uint8): 15, 2 -> 225
// f(uint8,uint8): 6, 3 -> 0xd8
// f(uint8,uint8): 7, 2 -> 0x31
// f(uint8,uint8): 7, 3 -> FAILURE
// f(uint8,uint8): 7, 4 -> FAILURE
// f(uint8,uint8): 255, 31 -> FAILURE
// f(uint8,uint8): 255, 131 -> FAILURE
// g(uint256,uint256): 0x200000000000000000000000000000000, 1 -> 0x0200000000000000000000000000000000
// g(uint256,uint256): 0x100000000000000000000000000000010, 2 -> FAILURE
// g(uint256,uint256): 0x200000000000000000000000000000000, 2 -> FAILURE
// g(uint256,uint256): 0x200000000000000000000000000000000, 3 -> FAILURE
// g(uint256,uint256): 255, 31 -> 400631961586894742455537928461950192806830589109049416147172451019287109375
// g(uint256,uint256): 255, 32 -> -13630939032658036097408813250890608687528184442832962921928608997994916749311
// g(uint256,uint256): 255, 33 -> FAILURE
// g(uint256,uint256): 255, 131 -> FAILURE
// g(uint256,uint256): 258, 31 -> 575719427506838823084316385994930914701079543089399988096291424922125729792
// g(uint256,uint256): 258, 37 -> FAILURE
// g(uint256,uint256): 258, 131 -> FAILURE
@@ -0,0 +1,50 @@
contract C {
function f(uint8 x, uint8 y) public returns (uint) {
return x**y;
}
function g(uint x, uint y) public returns (uint) {
return x**y;
}
}
// ====
// compileViaYul: also
// ----
// f(uint8,uint8): 0, 0 -> 1
// f(uint8,uint8): 0, 1 -> 0x00
// f(uint8,uint8): 0, 2 -> 0x00
// f(uint8,uint8): 0, 3 -> 0x00
// f(uint8,uint8): 1, 0 -> 1
// f(uint8,uint8): 1, 1 -> 1
// f(uint8,uint8): 1, 2 -> 1
// f(uint8,uint8): 1, 3 -> 1
// f(uint8,uint8): 2, 0 -> 1
// f(uint8,uint8): 2, 1 -> 2
// f(uint8,uint8): 2, 2 -> 4
// f(uint8,uint8): 2, 3 -> 8
// f(uint8,uint8): 3, 0 -> 1
// f(uint8,uint8): 3, 1 -> 3
// f(uint8,uint8): 3, 2 -> 9
// f(uint8,uint8): 3, 3 -> 0x1b
// f(uint8,uint8): 10, 0 -> 1
// f(uint8,uint8): 10, 1 -> 0x0a
// f(uint8,uint8): 10, 2 -> 100
// g(uint256,uint256): 0, 0 -> 1
// g(uint256,uint256): 0, 1 -> 0x00
// g(uint256,uint256): 0, 2 -> 0x00
// g(uint256,uint256): 0, 3 -> 0x00
// g(uint256,uint256): 1, 0 -> 1
// g(uint256,uint256): 1, 1 -> 1
// g(uint256,uint256): 1, 2 -> 1
// g(uint256,uint256): 1, 3 -> 1
// g(uint256,uint256): 2, 0 -> 1
// g(uint256,uint256): 2, 1 -> 2
// g(uint256,uint256): 2, 2 -> 4
// g(uint256,uint256): 2, 3 -> 8
// g(uint256,uint256): 3, 0 -> 1
// g(uint256,uint256): 3, 1 -> 3
// g(uint256,uint256): 3, 2 -> 9
// g(uint256,uint256): 3, 3 -> 0x1b
// g(uint256,uint256): 10, 10 -> 10000000000
// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936
// g(uint256,uint256): 256, 2 -> 0x010000
// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000