From 3a8eb793b3a4fe9465f46d32ae4e99f8290f0082 Mon Sep 17 00:00:00 2001 From: 1m1 Date: Thu, 27 Oct 2022 17:53:45 -0600 Subject: [PATCH 1/5] opcodes defined --- dev/TEAL_opcodes.md | 150 ++++++++++++++++++++++++++++++++------------ 1 file changed, 110 insertions(+), 40 deletions(-) diff --git a/dev/TEAL_opcodes.md b/dev/TEAL_opcodes.md index ea8cf6b..5a47a0c 100644 --- a/dev/TEAL_opcodes.md +++ b/dev/TEAL_opcodes.md @@ -1132,79 +1132,99 @@ The notation A,B indicates that A and B are interpreted as a uint128 value, with - **Cost**: 130 - Availability: v7 -## b+ +## b+ widthB widthD widthY - Opcode: 0xa0 -- Stack: ..., A: []byte, B: []byte → ..., []byte -- A plus B. A and B are interpreted as big-endian unsigned integers +- Stack: ..., A: uint64, B: []byte, C: uint64, D: []byte → ..., X: uint64, Y: []byte +- Addition of decimals. B and D are interpreted as big-endian unsigned integers. - **Cost**: 10 -- Availability: v4 +- Availability: v9 + +[(-1)^A * B * 10^widthB] + [(-1)^C * D * 10^widthD] = (-1)^X * Y * 10^widthY. widthB, widthD and widthY are uint64. widthY output precision is guaranteed. -## b- +## b- widthB widthD widthY - Opcode: 0xa1 -- Stack: ..., A: []byte, B: []byte → ..., []byte -- A minus B. A and B are interpreted as big-endian unsigned integers. Fail on underflow. +- Stack: ..., A: uint64, B: []byte, C: uint64, D: []byte → ..., X: uint64, Y: []byte +- Subtraction of decimals. B and D are interpreted as big-endian unsigned integers. Fail on underflow. - **Cost**: 10 -- Availability: v4 +- Availability: v9 -## b/ +[(-1)^A * B * 10^widthB] - [(-1)^C * D * 10^widthD] = (-1)^X * Y * 10^widthY. widthB, widthD and widthY are uint64. widthY output precision is guaranteed. + +## b/ widthB widthD widthY - Opcode: 0xa2 -- Stack: ..., A: []byte, B: []byte → ..., []byte -- A divided by B (truncated division). A and B are interpreted as big-endian unsigned integers. Fail if B is zero. +- Stack: ..., A: uint64, B: []byte, C: uint64, D: []byte → ..., X: uint64, Y: []byte +- Division of decimals (truncated division). B and D are interpreted as big-endian unsigned integers. Fail if D is zero. - **Cost**: 20 -- Availability: v4 +- Availability: v9 -## b* +[(-1)^A * B * 10^widthB] / [(-1)^C * D * 10^widthD] = (-1)^X * Y * 10^widthY. widthB, widthD and widthY are uint64. widthY output precision is guaranteed. + +## b* widthB widthD widthY - Opcode: 0xa3 -- Stack: ..., A: []byte, B: []byte → ..., []byte -- A times B. A and B are interpreted as big-endian unsigned integers. +- Stack: ..., A: uint64, B: []byte, C: uint64, D: []byte → ..., X: uint64, Y: []byte +- Multilpication of decimals. B and D are interpreted as big-endian unsigned integers. - **Cost**: 20 -- Availability: v4 +- Availability: v9 + +[(-1)^A * B * 10^widthB] * [(-1)^C * D * 10^widthD] = (-1)^X * Y * 10^widthY. widthB, widthD and widthY are uint64. widthY output precision is guaranteed. -## b< +## b< widthB widthD - Opcode: 0xa4 -- Stack: ..., A: []byte, B: []byte → ..., uint64 -- 1 if A is less than B, else 0. A and B are interpreted as big-endian unsigned integers -- Availability: v4 +- Stack: ..., A: uint, B: []byte, C: uint, D: []byte → ..., uint64 +- Less than, 1 if true, else 0. B and D are interpreted as big-endian unsigned integers. +- Availability: v9 -## b> +(-1)^A * B * 10^widthB < (-1)^C * D * 10^widthD. widthB and widthD are uint. + +## b> widthB widthD - Opcode: 0xa5 -- Stack: ..., A: []byte, B: []byte → ..., uint64 -- 1 if A is greater than B, else 0. A and B are interpreted as big-endian unsigned integers -- Availability: v4 +- Stack: ..., A: uint, B: []byte, C: uint, D: []byte → ..., uint64 +- Greater than, 1 if true, else 0. B and D are interpreted as big-endian unsigned integers. +- Availability: v9 -## b<= +(-1)^A * B * 10^widthB > (-1)^C * D * 10^widthD. widthB and widthD are uint. + +## b<= widthB widthD - Opcode: 0xa6 -- Stack: ..., A: []byte, B: []byte → ..., uint64 -- 1 if A is less than or equal to B, else 0. A and B are interpreted as big-endian unsigned integers -- Availability: v4 +- Stack: ..., A: uint, B: []byte, C: uint, D: []byte → ..., uint64 +- Less than xor equal, 1 if true, else 0. B and D are interpreted as big-endian unsigned integers. +- Availability: v9 + +(-1)^A * B * 10^widthB <= (-1)^C * D * 10^widthD. widthB and widthD are uint. -## b>= +## b>= widthB widthD - Opcode: 0xa7 -- Stack: ..., A: []byte, B: []byte → ..., uint64 -- 1 if A is greater than or equal to B, else 0. A and B are interpreted as big-endian unsigned integers -- Availability: v4 +- Stack: ..., A: uint, B: []byte, C: uint, D: []byte → ..., uint64 +- Greater than xor equal, 1 if true, else 0. B and D are interpreted as big-endian unsigned integers. +- Availability: v9 + +(-1)^A * B * 10^widthB >= (-1)^C * D * 10^widthD. widthB and widthD are uint. -## b== +## b== widthB widthD - Opcode: 0xa8 -- Stack: ..., A: []byte, B: []byte → ..., uint64 -- 1 if A is equal to B, else 0. A and B are interpreted as big-endian unsigned integers -- Availability: v4 +- Stack: ..., A: uint, B: []byte, C: uint, D: []byte → ..., uint64 +- Equal, 1 if true, else 0. B and D are interpreted as big-endian unsigned integers. +- Availability: v9 + +(-1)^A * B * 10^widthB == (-1)^C * D * 10^widthD. widthB and widthD are uint. -## b!= +## b!= widthB widthD - Opcode: 0xa9 -- Stack: ..., A: []byte, B: []byte → ..., uint64 -- 0 if A is equal to B, else 1. A and B are interpreted as big-endian unsigned integers -- Availability: v4 +- Stack: ..., A: uint, B: []byte, C: uint, D: []byte → ..., uint64 +- Not equal, 1 if true, else 0. B and D are interpreted as big-endian unsigned integers. +- Availability: v9 + +(-1)^A * B * 10^widthB != (-1)^C * D * 10^widthD. widthB and widthD are uint. ## b% @@ -1253,6 +1273,56 @@ The notation A,B indicates that A and B are interpreted as a uint128 value, with - zero filled byte-array of length A - Availability: v4 +## bpow widthB widthD widthY + +- Opcode: 0x?? +- Stack: ..., A: uint, B: []byte, C: uint, D: []byte → ..., X: uint, Y: []byte +- Decimal to the power of a decimal. B and D are interpreted as big-endian unsigned integers. +- **Cost**: base cost plus cost dependent on widthY +- Availability: v9 + +[(-1)^A * B * 10^widthB] ^ [(-1)^C * D * 10^widthD] = (-1)^X * Y * 10^widthY. widthB, widthD and widthY are uint64. widthY output precision is guaranteed. + +## bexp widthB widthY + +- Opcode: 0x?? +- Stack: ..., A: uint, B: []byte → ..., Y: []byte +- e to the power of a decimal. B is interpreted as big-endian unsigned integers. +- **Cost**: base cost plus cost dependent on widthY +- Availability: v9 + +exp[(-1)^A * B * 10^widthB] = Y * 10^widthY. widthB and widthY are uint64. widthY output precision is guaranteed. + +## bln widthA widthY + +- Opcode: 0x?? +- Stack: ..., A: []byte → ..., X: uint, Y: []byte +- Natural logarithm of a decimal. A is interpreted as big-endian unsigned integers. +- **Cost**: base cost plus cost dependent on widthY +- Availability: v9 + +ln[A * 10^widthA] = (-1)^X * Y * 10^widthY. widthA and widthY are uint64. widthY output precision is guaranteed. + +## blog2 widthA widthY + +- Opcode: 0x?? +- Stack: ..., A: []byte → ..., X: uint, Y: []byte +- Logarithm base 2 of a decimal. A is interpreted as big-endian unsigned integers. +- **Cost**: base cost plus cost dependent on widthY +- Availability: v9 + +log2[A * 10^widthA] = (-1)^X * Y * 10^widthY. widthA and widthY are uint64. widthY output precision is guaranteed. + +## blog10 widthA widthY + +- Opcode: 0x?? +- Stack: ..., A: []byte → ..., X: uint, Y: []byte +- Logarithm base 10 of a decimal. A is interpreted as big-endian unsigned integers. +- **Cost**: base cost plus cost dependent on widthY +- Availability: v9 + +log10[A * 10^widthA] = (-1)^X * Y * 10^widthY. widthA and widthY are uint64. widthY output precision is guaranteed. + ## log - Opcode: 0xb0 From 69e19cfff5b99ce2eb558d7299f25fd2ad27efe6 Mon Sep 17 00:00:00 2001 From: 1m1 Date: Thu, 27 Oct 2022 18:01:42 -0600 Subject: [PATCH 2/5] decimal defined --- dev/TEAL.md | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/dev/TEAL.md b/dev/TEAL.md index 05fde43..9c6abc5 100644 --- a/dev/TEAL.md +++ b/dev/TEAL.md @@ -337,11 +337,14 @@ return stack matches the name of the input value. | `json_ref r` | key B's value, of type R, from a [valid](jsonspec.md) utf-8 encoded json object A | The following opcodes take byte-array values that are interpreted as -big-endian unsigned integers. For mathematical operators, the +decimals. For mathematical operators, the returned values are the shortest byte-array that can represent the returned value. For example, the zero value is the empty byte-array. For comparison operators, the returned value is a uint64. +Decimals are interpreted as follows: +Given A: uint64, B: []byte, width: uint64, interpret B as a big-endian unsigned integer and multiply that with (-1)^A*10^width + Input lengths are limited to a maximum length of 64 bytes, representing a 512 bit unsigned integer. Output lengths are not explicitly restricted, though only `b*` and `b+` can produce a larger @@ -350,18 +353,23 @@ bytes on outputs. | Opcode | Description | | - | -- | -| `b+` | A plus B. A and B are interpreted as big-endian unsigned integers | -| `b-` | A minus B. A and B are interpreted as big-endian unsigned integers. Fail on underflow. | -| `b/` | A divided by B (truncated division). A and B are interpreted as big-endian unsigned integers. Fail if B is zero. | -| `b*` | A times B. A and B are interpreted as big-endian unsigned integers. | -| `b<` | 1 if A is less than B, else 0. A and B are interpreted as big-endian unsigned integers | -| `b>` | 1 if A is greater than B, else 0. A and B are interpreted as big-endian unsigned integers | -| `b<=` | 1 if A is less than or equal to B, else 0. A and B are interpreted as big-endian unsigned integers | -| `b>=` | 1 if A is greater than or equal to B, else 0. A and B are interpreted as big-endian unsigned integers | -| `b==` | 1 if A is equal to B, else 0. A and B are interpreted as big-endian unsigned integers | -| `b!=` | 0 if A is equal to B, else 1. A and B are interpreted as big-endian unsigned integers | +| `b+` | Addition of decimals. | +| `b-` | Subtraction of decimals. Fail on underflow. | +| `b/` | Division of decimals (truncated division). Fail if B is zero. | +| `b*` | Multilpication of decimals. | +| `b<` | Less than, 1 if true, else 0. | +| `b>` | Greater than, 1 if true, else 0. | +| `b<=` | Less than xor equal, 1 if true, else 0. | +| `b>=` | Greater than xor equal, 1 if true, else 0. | +| `b==` | Equal, 1 if true, else 0. | +| `b!=` | Not equal, 1 if true, else 0. | | `b%` | A modulo B. A and B are interpreted as big-endian unsigned integers. Fail if B is zero. | -| `bsqrt` | The largest integer I such that I^2 <= A. A and I are interpreted as big-endian unsigned integers | +| `bsqrt` | The largest integer I such that I^2 <= A. A and I are interpreted as big-endian unsigned integers. | +| `bpow` | Decimal to the power of a decimal. | +| `bexp` | e to the power of a decimal. | +| `bln` | Natural logarithm of a decimal. | +| `blog2` | Logarithm base 2 of a decimal. | +| `blog10` | Logarithm base 10 of a decimal. | These opcodes operate on the bits of byte-array values. The shorter input array is interpreted as though left padded with zeros until it is the From bbafa5864a9a9566760a80a51e787de920ed9599 Mon Sep 17 00:00:00 2001 From: 1m1 Date: Thu, 27 Oct 2022 18:06:04 -0600 Subject: [PATCH 3/5] calculation details added --- dev/TEAL_opcodes.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dev/TEAL_opcodes.md b/dev/TEAL_opcodes.md index 5a47a0c..4909b69 100644 --- a/dev/TEAL_opcodes.md +++ b/dev/TEAL_opcodes.md @@ -1282,6 +1282,7 @@ The notation A,B indicates that A and B are interpreted as a uint128 value, with - Availability: v9 [(-1)^A * B * 10^widthB] ^ [(-1)^C * D * 10^widthD] = (-1)^X * Y * 10^widthY. widthB, widthD and widthY are uint64. widthY output precision is guaranteed. +Calculation is based on the following identity: q^w = exp(ln(q)/w). ## bexp widthB widthY @@ -1292,6 +1293,7 @@ The notation A,B indicates that A and B are interpreted as a uint128 value, with - Availability: v9 exp[(-1)^A * B * 10^widthB] = Y * 10^widthY. widthB and widthY are uint64. widthY output precision is guaranteed. +Calculation is based on the Taylor expansion of e^q. ## bln widthA widthY @@ -1302,6 +1304,7 @@ exp[(-1)^A * B * 10^widthB] = Y * 10^widthY. widthB and widthY are uint64. width - Availability: v9 ln[A * 10^widthA] = (-1)^X * Y * 10^widthY. widthA and widthY are uint64. widthY output precision is guaranteed. +Calculation is based on the following identity: ln(q) = log2(q) / log2(e) ## blog2 widthA widthY @@ -1312,6 +1315,7 @@ ln[A * 10^widthA] = (-1)^X * Y * 10^widthY. widthA and widthY are uint64. widthY - Availability: v9 log2[A * 10^widthA] = (-1)^X * Y * 10^widthY. widthA and widthY are uint64. widthY output precision is guaranteed. +Calculation is based on the on a binary appromixation that allows arbitrary precision. ## blog10 widthA widthY @@ -1322,6 +1326,7 @@ log2[A * 10^widthA] = (-1)^X * Y * 10^widthY. widthA and widthY are uint64. widt - Availability: v9 log10[A * 10^widthA] = (-1)^X * Y * 10^widthY. widthA and widthY are uint64. widthY output precision is guaranteed. +Calculation is based on the following identity: log10(q) = log2(q) / log2(10) ## log From 1a33c11f30ea32054584ac2d19dd49a6427f7b5d Mon Sep 17 00:00:00 2001 From: 1m1 Date: Thu, 27 Oct 2022 18:56:33 -0600 Subject: [PATCH 4/5] width is uint, need extra stack param to convert to int --- dev/TEAL.md | 3 +- dev/TEAL_opcodes.md | 75 +++++++++++++++++++++++++++------------------ 2 files changed, 47 insertions(+), 31 deletions(-) diff --git a/dev/TEAL.md b/dev/TEAL.md index 9c6abc5..2e3a9e3 100644 --- a/dev/TEAL.md +++ b/dev/TEAL.md @@ -343,7 +343,8 @@ returned value. For example, the zero value is the empty byte-array. For comparison operators, the returned value is a uint64. Decimals are interpreted as follows: -Given A: uint64, B: []byte, width: uint64, interpret B as a big-endian unsigned integer and multiply that with (-1)^A*10^width +Given A: uint64, B: []byte, width: uint64, E: uint64 interpret B as a big-endian unsigned integer and multiply that with: +(-1)^A * 10^((-1)^E * width) Input lengths are limited to a maximum length of 64 bytes, representing a 512 bit unsigned integer. Output lengths are not diff --git a/dev/TEAL_opcodes.md b/dev/TEAL_opcodes.md index 4909b69..de73849 100644 --- a/dev/TEAL_opcodes.md +++ b/dev/TEAL_opcodes.md @@ -1135,96 +1135,106 @@ The notation A,B indicates that A and B are interpreted as a uint128 value, with ## b+ widthB widthD widthY - Opcode: 0xa0 -- Stack: ..., A: uint64, B: []byte, C: uint64, D: []byte → ..., X: uint64, Y: []byte +- Stack: ..., A: uint64, B: []byte, C: uint64, D: []byte, E: uint64, F: uint64, G: uint64 → ..., X: uint64, Y: []byte - Addition of decimals. B and D are interpreted as big-endian unsigned integers. - **Cost**: 10 - Availability: v9 -[(-1)^A * B * 10^widthB] + [(-1)^C * D * 10^widthD] = (-1)^X * Y * 10^widthY. widthB, widthD and widthY are uint64. widthY output precision is guaranteed. +wB = (-1)^E * widthB ; wD = (-1)^F * widthD ; wY = (-1)^G * widthY +[(-1)^A * B * 10^wB] + [(-1)^C * D * 10^wD] = (-1)^X * Y * 10^wY. widthB, widthD and widthY are uint64. widthY decimal output precision is guaranteed. ## b- widthB widthD widthY - Opcode: 0xa1 -- Stack: ..., A: uint64, B: []byte, C: uint64, D: []byte → ..., X: uint64, Y: []byte +- Stack: ..., A: uint64, B: []byte, C: uint64, D: []byte, E: uint64, F: uint64, G: uint64 → ..., X: uint64, Y: []byte - Subtraction of decimals. B and D are interpreted as big-endian unsigned integers. Fail on underflow. - **Cost**: 10 - Availability: v9 -[(-1)^A * B * 10^widthB] - [(-1)^C * D * 10^widthD] = (-1)^X * Y * 10^widthY. widthB, widthD and widthY are uint64. widthY output precision is guaranteed. +wB = (-1)^E * widthB ; wD = (-1)^F * widthD ; wY = (-1)^G * widthY +[(-1)^A * B * 10^wB] - [(-1)^C * D * 10^wD] = (-1)^X * Y * 10^wY. widthB, widthD and widthY are uint64. widthY output precision is guaranteed. ## b/ widthB widthD widthY - Opcode: 0xa2 -- Stack: ..., A: uint64, B: []byte, C: uint64, D: []byte → ..., X: uint64, Y: []byte +- Stack: ..., A: uint64, B: []byte, C: uint64, D: []byte, E: uint64, F: uint64, G: uint64 → ..., X: uint64, Y: []byte - Division of decimals (truncated division). B and D are interpreted as big-endian unsigned integers. Fail if D is zero. - **Cost**: 20 - Availability: v9 -[(-1)^A * B * 10^widthB] / [(-1)^C * D * 10^widthD] = (-1)^X * Y * 10^widthY. widthB, widthD and widthY are uint64. widthY output precision is guaranteed. +wB = (-1)^E * widthB ; wD = (-1)^F * widthD ; wY = (-1)^G * widthY +[(-1)^A * B * 10^wB] / [(-1)^C * D * 10^wD] = (-1)^X * Y * 10^wY. widthB, widthD and widthY are uint64. widthY output precision is guaranteed. ## b* widthB widthD widthY - Opcode: 0xa3 -- Stack: ..., A: uint64, B: []byte, C: uint64, D: []byte → ..., X: uint64, Y: []byte +- Stack: ..., A: uint64, B: []byte, C: uint64, D: []byte, E: uint64, F: uint64, G: uint64 → ..., X: uint64, Y: []byte - Multilpication of decimals. B and D are interpreted as big-endian unsigned integers. - **Cost**: 20 - Availability: v9 -[(-1)^A * B * 10^widthB] * [(-1)^C * D * 10^widthD] = (-1)^X * Y * 10^widthY. widthB, widthD and widthY are uint64. widthY output precision is guaranteed. +wB = (-1)^E * widthB ; wD = (-1)^F * widthD ; wY = (-1)^G * widthY +[(-1)^A * B * 10^wB] * [(-1)^C * D * 10^wD] = (-1)^X * Y * 10^wY. widthB, widthD and widthY are uint64. widthY output precision is guaranteed. ## b< widthB widthD - Opcode: 0xa4 -- Stack: ..., A: uint, B: []byte, C: uint, D: []byte → ..., uint64 +- Stack: ..., A: uint, B: []byte, C: uint, D: []byte, E: uint64, F: uint64 → ..., uint64 - Less than, 1 if true, else 0. B and D are interpreted as big-endian unsigned integers. - Availability: v9 -(-1)^A * B * 10^widthB < (-1)^C * D * 10^widthD. widthB and widthD are uint. +wB = (-1)^E * widthB ; wD = (-1)^F * widthD +(-1)^A * B * 10^wB < (-1)^C * D * 10^wD. widthB and widthD are uint. ## b> widthB widthD - Opcode: 0xa5 -- Stack: ..., A: uint, B: []byte, C: uint, D: []byte → ..., uint64 +- Stack: ..., A: uint, B: []byte, C: uint, D: []byte, E: uint64, F: uint64 → ..., uint64 - Greater than, 1 if true, else 0. B and D are interpreted as big-endian unsigned integers. - Availability: v9 -(-1)^A * B * 10^widthB > (-1)^C * D * 10^widthD. widthB and widthD are uint. +wB = (-1)^E * widthB ; wD = (-1)^F * widthD +(-1)^A * B * 10^wB > (-1)^C * D * 10^wD. widthB and widthD are uint. ## b<= widthB widthD - Opcode: 0xa6 -- Stack: ..., A: uint, B: []byte, C: uint, D: []byte → ..., uint64 +- Stack: ..., A: uint, B: []byte, C: uint, D: []byte, E: uint64, F: uint64 → ..., uint64 - Less than xor equal, 1 if true, else 0. B and D are interpreted as big-endian unsigned integers. - Availability: v9 -(-1)^A * B * 10^widthB <= (-1)^C * D * 10^widthD. widthB and widthD are uint. +wB = (-1)^E * widthB ; wD = (-1)^F * widthD +(-1)^A * B * 10^wB <= (-1)^C * D * 10^wD. widthB and widthD are uint. ## b>= widthB widthD - Opcode: 0xa7 -- Stack: ..., A: uint, B: []byte, C: uint, D: []byte → ..., uint64 +- Stack: ..., A: uint, B: []byte, C: uint, D: []byte, E: uint64, F: uint64 → ..., uint64 - Greater than xor equal, 1 if true, else 0. B and D are interpreted as big-endian unsigned integers. - Availability: v9 -(-1)^A * B * 10^widthB >= (-1)^C * D * 10^widthD. widthB and widthD are uint. +wB = (-1)^E * widthB ; wD = (-1)^F * widthD +(-1)^A * B * 10^wB >= (-1)^C * D * 10^wD. widthB and widthD are uint. ## b== widthB widthD - Opcode: 0xa8 -- Stack: ..., A: uint, B: []byte, C: uint, D: []byte → ..., uint64 +- Stack: ..., A: uint, B: []byte, C: uint, D: []byte, E: uint64, F: uint64 → ..., uint64 - Equal, 1 if true, else 0. B and D are interpreted as big-endian unsigned integers. - Availability: v9 -(-1)^A * B * 10^widthB == (-1)^C * D * 10^widthD. widthB and widthD are uint. +wB = (-1)^E * widthB ; wD = (-1)^F * widthD +(-1)^A * B * 10^wB == (-1)^C * D * 10^wD. widthB and widthD are uint. ## b!= widthB widthD - Opcode: 0xa9 -- Stack: ..., A: uint, B: []byte, C: uint, D: []byte → ..., uint64 +- Stack: ..., A: uint, B: []byte, C: uint, D: []byte, E: uint64, F: uint64 → ..., uint64 - Not equal, 1 if true, else 0. B and D are interpreted as big-endian unsigned integers. - Availability: v9 -(-1)^A * B * 10^widthB != (-1)^C * D * 10^widthD. widthB and widthD are uint. +wB = (-1)^E * widthB ; wD = (-1)^F * widthD +(-1)^A * B * 10^wB != (-1)^C * D * 10^wD. widthB and widthD are uint. ## b% @@ -1276,56 +1286,61 @@ The notation A,B indicates that A and B are interpreted as a uint128 value, with ## bpow widthB widthD widthY - Opcode: 0x?? -- Stack: ..., A: uint, B: []byte, C: uint, D: []byte → ..., X: uint, Y: []byte +- Stack: ..., A: uint, B: []byte, C: uint, D: []byte, E: uint64, F: uint64, G: uint64 → ..., X: uint, Y: []byte - Decimal to the power of a decimal. B and D are interpreted as big-endian unsigned integers. - **Cost**: base cost plus cost dependent on widthY - Availability: v9 -[(-1)^A * B * 10^widthB] ^ [(-1)^C * D * 10^widthD] = (-1)^X * Y * 10^widthY. widthB, widthD and widthY are uint64. widthY output precision is guaranteed. +wB = (-1)^E * widthB ; wD = (-1)^F * widthD ; wY = (-1)^G * widthY +[(-1)^A * B * 10^wB] ^ [(-1)^C * D * 10^wD] = (-1)^X * Y * 10^wY. widthB, widthD and widthY are uint64. widthY output precision is guaranteed. Calculation is based on the following identity: q^w = exp(ln(q)/w). ## bexp widthB widthY - Opcode: 0x?? -- Stack: ..., A: uint, B: []byte → ..., Y: []byte +- Stack: ..., A: uint, B: []byte, E: uint64, F: uint64 → ..., Y: []byte - e to the power of a decimal. B is interpreted as big-endian unsigned integers. - **Cost**: base cost plus cost dependent on widthY - Availability: v9 -exp[(-1)^A * B * 10^widthB] = Y * 10^widthY. widthB and widthY are uint64. widthY output precision is guaranteed. +wB = (-1)^E * widthB ; wY = (-1)^F * widthY +exp[(-1)^A * B * 10^wB] = Y * 10^wY. widthB and widthY are uint64. widthY output precision is guaranteed. Calculation is based on the Taylor expansion of e^q. ## bln widthA widthY - Opcode: 0x?? -- Stack: ..., A: []byte → ..., X: uint, Y: []byte +- Stack: ..., A: []byte, E: uint64, F: uint64 → ..., X: uint, Y: []byte - Natural logarithm of a decimal. A is interpreted as big-endian unsigned integers. - **Cost**: base cost plus cost dependent on widthY - Availability: v9 -ln[A * 10^widthA] = (-1)^X * Y * 10^widthY. widthA and widthY are uint64. widthY output precision is guaranteed. +wA = (-1)^E * widthA ; wY = (-1)^F * widthY +ln[A * 10^wA] = (-1)^X * Y * 10^wY. widthA and widthY are uint64. widthY output precision is guaranteed. Calculation is based on the following identity: ln(q) = log2(q) / log2(e) ## blog2 widthA widthY - Opcode: 0x?? -- Stack: ..., A: []byte → ..., X: uint, Y: []byte +- Stack: ..., A: []byte, E: uint64, F: uint64 → ..., X: uint, Y: []byte - Logarithm base 2 of a decimal. A is interpreted as big-endian unsigned integers. - **Cost**: base cost plus cost dependent on widthY - Availability: v9 -log2[A * 10^widthA] = (-1)^X * Y * 10^widthY. widthA and widthY are uint64. widthY output precision is guaranteed. +wA = (-1)^E * widthA ; wY = (-1)^F * widthY +log2[A * 10^wA] = (-1)^X * Y * 10^wY. widthA and widthY are uint64. widthY output precision is guaranteed. Calculation is based on the on a binary appromixation that allows arbitrary precision. ## blog10 widthA widthY - Opcode: 0x?? -- Stack: ..., A: []byte → ..., X: uint, Y: []byte +- Stack: ..., A: []byte, E: uint64, F: uint64 → ..., X: uint, Y: []byte - Logarithm base 10 of a decimal. A is interpreted as big-endian unsigned integers. - **Cost**: base cost plus cost dependent on widthY - Availability: v9 -log10[A * 10^widthA] = (-1)^X * Y * 10^widthY. widthA and widthY are uint64. widthY output precision is guaranteed. +wA = (-1)^E * widthA ; wY = (-1)^F * widthY +log10[A * 10^wA] = (-1)^X * Y * 10^wY. widthA and widthY are uint64. widthY output precision is guaranteed. Calculation is based on the following identity: log10(q) = log2(q) / log2(10) ## log From 7c060054b2f4f1a0a5a0f4d5f0aa38ca9f4ddfcc Mon Sep 17 00:00:00 2001 From: 1m1 <77983409+1m1-github@users.noreply.github.com> Date: Fri, 21 Jun 2024 14:00:25 -0700 Subject: [PATCH 5/5] remove unnecessary opcodes --- dev/TEAL_opcodes.md | 36 ++++++------------------------------ 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/dev/TEAL_opcodes.md b/dev/TEAL_opcodes.md index d0c17d0..24d0007 100644 --- a/dev/TEAL_opcodes.md +++ b/dev/TEAL_opcodes.md @@ -1370,18 +1370,6 @@ wB = (-1)^E * widthB ; wD = (-1)^F * widthD - zero filled byte-array of length A - Availability: v4 -## bpow widthB widthD widthY - -- Opcode: 0x?? -- Stack: ..., A: uint, B: []byte, C: uint, D: []byte, E: uint64, F: uint64, G: uint64 → ..., X: uint, Y: []byte -- Decimal to the power of a decimal. B and D are interpreted as big-endian unsigned integers. -- **Cost**: base cost plus cost dependent on widthY -- Availability: v9 - -wB = (-1)^E * widthB ; wD = (-1)^F * widthD ; wY = (-1)^G * widthY -[(-1)^A * B * 10^wB] ^ [(-1)^C * D * 10^wD] = (-1)^X * Y * 10^wY. widthB, widthD and widthY are uint64. widthY output precision is guaranteed. -Calculation is based on the following identity: q^w = exp(ln(q)/w). - ## bexp widthB widthY - Opcode: 0x?? @@ -1406,29 +1394,17 @@ wA = (-1)^E * widthA ; wY = (-1)^F * widthY ln[A * 10^wA] = (-1)^X * Y * 10^wY. widthA and widthY are uint64. widthY output precision is guaranteed. Calculation is based on the following identity: ln(q) = log2(q) / log2(e) -## blog2 widthA widthY - -- Opcode: 0x?? -- Stack: ..., A: []byte, E: uint64, F: uint64 → ..., X: uint, Y: []byte -- Logarithm base 2 of a decimal. A is interpreted as big-endian unsigned integers. -- **Cost**: base cost plus cost dependent on widthY -- Availability: v9 - -wA = (-1)^E * widthA ; wY = (-1)^F * widthY -log2[A * 10^wA] = (-1)^X * Y * 10^wY. widthA and widthY are uint64. widthY output precision is guaranteed. -Calculation is based on the on a binary appromixation that allows arbitrary precision. - -## blog10 widthA widthY +## bsin widthB widthY - Opcode: 0x?? -- Stack: ..., A: []byte, E: uint64, F: uint64 → ..., X: uint, Y: []byte -- Logarithm base 10 of a decimal. A is interpreted as big-endian unsigned integers. +- Stack: ..., A: uint, B: []byte, E: uint64, F: uint64 → ..., X: uint, Y: []byte +- Decimal to the power of a decimal. B and Y are interpreted as big-endian unsigned integers. - **Cost**: base cost plus cost dependent on widthY - Availability: v9 -wA = (-1)^E * widthA ; wY = (-1)^F * widthY -log10[A * 10^wA] = (-1)^X * Y * 10^wY. widthA and widthY are uint64. widthY output precision is guaranteed. -Calculation is based on the following identity: log10(q) = log2(q) / log2(10) +wB = (-1)^E * widthB ; wY = (-1)^F * widthY +sin((-1)^A * B * 10^wB) = (-1)^X * Y * 10^wY. widthB and widthY are uint64. widthY output precision is guaranteed. +Calculation is based on the Taylor expansion of sin(q). ## log