# Arithmetic Operations

An arithmetic expression is an expression that results in a `TealType.uint64` value. In PyTeal, arithmetic expressions include integer and boolean operators (booleans are the integers 0 or 1). The table below summarized all arithmetic expressions in PyTeal.

Operator

Semantics

Example

`Lt(a, b)`

`a < b`

1 if a is less than b, 0 otherwise

`Int(1) < Int(5)`

`Gt(a, b)`

`a > b`

1 if a is greater than b, 0 otherwise

`Int(1) > Int(5)`

`Le(a, b)`

`a <= b`

1 if a is no greater than b, 0 otherwise

`Int(1) <= Int(5)`

`Ge(a, b)`

`a >= b`

1 if a is no less than b, 0 otherwise

`Int(1) >= Int(5)`

`Add(a, b)`

`a + b`

a + b, error (panic) if overflow

`Int(1) + Int(5)`

`Minus(a, b)`

`a - b`

a - b, error if underflow

`Int(5) - Int(1)`

`Mul(a, b)`

`a * b`

a * b, error if overflow

`Int(2) * Int(3)`

`Div(a, b)`

`a / b`

a / b, error if divided by zero

`Int(3) / Int(2)`

`Mod(a, b)`

`a % b`

a % b, modulo operation

`Int(7) % Int(3)`

`Exp(a, b)`

`a ** b`

a ** b, exponent operation

`Int(7) ** Int(3)`

`Eq(a, b)`

`a == b`

1 if a equals b, 0 otherwise

`Int(7) == Int(7)`

`Neq(a, b)`

`a != b`

0 if a equals b, 1 otherwise

`Int(7) != Int(7)`

`And(a, b)`

1 if a > 0 && b > 0, 0 otherwise

`And(Int(1), Int(1))`

`Or(a, b)`

1 if a > 0 || b > 0, 0 otherwise

`Or(Int(1), Int(0))`

`Not(a)`

1 if a equals 0, 0 otherwise

`Not(Int(0))`

`BitwiseAnd(a,b)`

`a & b`

a & b, bitwise and operation

`Int(1) & Int(3)`

`BitwiseOr(a,b)`

`a | b`

a | b, bitwise or operation

`Int(2) | Int(5)`

`BitwiseXor(a,b)`

`a ^ b`

a ^ b, bitwise xor operation

`Int(3) ^ Int(7)`

`BitwiseNot(a)`

`~a`

~a, bitwise complement operation

`~Int(1)`

Most of the above operations take two `TealType.uint64` values as inputs. In addition, `Eq(a, b)` (`==`) and `Neq(a, b)` (`!=`) also work for byte slices. For example, `Arg(0) == Arg(1)` and `Arg(0) != Arg(1)` are valid PyTeal expressions.

Both `And` and `Or` also support more than 2 arguments when called as functions:

• `And(a, b, ...)`

• `Or(a, b, ...)`

The associativity and precedence of the overloaded Python arithmetic operators are the same as the original python operators . For example:

• `Int(1) + Int(2) + Int(3)` is equivalent to `Add(Add(Int(1), Int(2)), Int(3))`

• `Int(1) + Int(2) * Int(3)` is equivalent to `Add(Int(1), Mul(Int(2), Int(3)))`

## Byteslice Arithmetic

Byteslice arithmetic is available for AVM V4 and above. Byteslice arithmetic operators allow up to 512-bit arithmetic. In PyTeal, byteslice arithmetic expressions include `TealType.Bytes` values as arguments (with the exception of `BytesZero`) and must be 64 bytes or less. The table below summarizes the byteslize arithmetic operations in PyTeal.

Operator

Return Type

Example

Example Result

`BytesLt(a, b)`

`TealType.uint64`

`BytesLt(Bytes("base16", "0xFF"), Bytes("base16", "0xFE"))`

`0`

`BytesGt(a, b)`

`TealType.uint64`

`BytesGt(Bytes("base16", "0xFF"), Bytes("base16", "0xFE"))`

`1`

`BytesLe(a, b)`

`TealType.uint64`

`BytesLe(Bytes("base16", "0xFF"), Bytes("base16", "0xFE"))`

`0`

`BytesGe(a, b)`

`TealType.uint64`

`BytesGe(Bytes("base16", "0xFF"), Bytes("base16", "0xFE"))`

`1`

`BytesEq(a, b)`

`TealType.uint64`

`BytesEq(Bytes("base16", "0xFF"), Bytes("base16", "0xFF"))`

`1`

`BytesNeq(a, b)`

`TealType.uint64`

`BytesNeq(Bytes("base16", "0xFF"), Bytes("base16", "0xFF"))`

`0`

`BytesAdd(a, b)`

`TealType.Bytes`

`BytesAdd(Bytes("base16", "0xFF"), Bytes("base16", "0xFE"))`

`0x01FD`

`BytesMinus(a, b)`

`TealType.Bytes`

`BytesMinus(Bytes("base16", "0xFF"), Bytes("base16", "0xFE"))`

`0x01`

`BytesMul(a, b)`

`TealType.Bytes`

`BytesMul(Bytes("base16", "0xFF"), Bytes("base16", "0xFE"))`

`0xFD02`

`BytesDiv(a, b)`

`TealType.Bytes`

`BytesDiv(Bytes("base16", "0xFF"), Bytes("base16", "0x11"))`

`0x0F`

`BytesMod(a, b)`

`TealType.Bytes`

`BytesMod(Bytes("base16", "0xFF"), Bytes("base16", "0x12"))`

`0x03`

`BytesAnd(a, b)`

`TealType.Bytes`

`BytesAnd(Bytes("base16", "0xBEEF"), Bytes("base16", "0x1337"))`

`0x1227`

`BytesOr(a, b)`

`TealType.Bytes`

`BytesOr(Bytes("base16", "0xBEEF"), Bytes("base16", "0x1337"))`

`0xBFFF`

`BytesXor(a, b)`

`TealType.Bytes`

`BytesXor(Bytes("base16", "0xBEEF"), Bytes("base16", "0x1337"))`

`0xADD8`

`BytesNot(a)`

`TealType.Bytes`

`BytesNot(Bytes("base16", "0xFF00"))`

`0x00FF`

`BytesZero(a)`

`TealType.Bytes`

`BytesZero(Int(4))`

`0x00000000`

Currently, byteslice arithmetic operations are not overloaded, and must be explicitly called.

## Bit and Byte Operations

In addition to the standard arithmetic operators above, PyTeal also supports operations that manipulate the individual bits and bytes of PyTeal values.

To use these operations, you’ll need to provide an index specifying which bit or byte to access. These indexes have different meanings depending on whether you are manipulating integers or byte slices:

• For integers, bit indexing begins with low-order bits. For example, the bit at index 4 of the integer 16 (`000...0001000` in binary) is 1. Every other index has a bit value of 0. Any index less than 64 is valid, regardless of the integer’s value.

Byte indexing is not supported for integers.

• For byte strings, bit indexing begins at the first bit. For example, the bit at index 0 of the base16 byte string `0xf0` (`11110000` in binary) is 1. Any index less than 4 has a bit value of 1, and any index 4 or greater has a bit value of 0. Any index less than 8 times the length of the byte string is valid.

Likewise, byte indexing begins at the first byte of the string. For example, the byte at index 0 of that the base16 string `0xff00` (`1111111100000000` in binary) is 255 (`111111111` in binary), and the byte at index 1 is 0. Any index less than the length of the byte string is valid.

### Bit Manipulation

The `GetBit` expression can extract individual bit values from integers and byte strings. For example,

```GetBit(Int(16), Int(0)) # get the 0th bit of 16, produces 0
GetBit(Int(16), Int(4)) # get the 4th bit of 16, produces 1
GetBit(Int(16), Int(63)) # get the 63rd bit of 16, produces 0
GetBit(Int(16), Int(64)) # get the 64th bit of 16, invalid index

GetBit(Bytes("base16", "0xf0"), Int(0)) # get the 0th bit of 0xf0, produces 1
GetBit(Bytes("base16", "0xf0"), Int(7)) # get the 7th bit of 0xf0, produces 0
GetBit(Bytes("base16", "0xf0"), Int(8)) # get the 8th bit of 0xf0, invalid index
```

Additionally, the `SetBit` expression can modify individual bit values from integers and byte strings. For example,

```SetBit(Int(0), Int(4), Int(1)) # set the 4th bit of 0 to 1, produces 16
SetBit(Int(4), Int(0), Int(1)) # set the 0th bit of 4 to 1, produces 5
SetBit(Int(4), Int(0), Int(0)) # set the 0th bit of 4 to 0, produces 4

SetBit(Bytes("base16", "0x00"), Int(0), Int(1)) # set the 0th bit of 0x00 to 1, produces 0x80
SetBit(Bytes("base16", "0x00"), Int(3), Int(1)) # set the 3rd bit of 0x00 to 1, produces 0x10
SetBit(Bytes("base16", "0x00"), Int(7), Int(1)) # set the 7th bit of 0x00 to 1, produces 0x01
```

### Byte Manipulation

In addition to manipulating bits, individual bytes in byte strings can be manipulated.

The `GetByte` expression can extract individual bytes from byte strings. For example,

```GetByte(Bytes("base16", "0xff00"), Int(0)) # get the 0th byte of 0xff00, produces 255
GetByte(Bytes("base16", "0xff00"), Int(1)) # get the 1st byte of 0xff00, produces 0
GetByte(Bytes("base16", "0xff00"), Int(2)) # get the 2nd byte of 0xff00, invalid index

GetByte(Bytes("abc"), Int(0)) # get the 0th byte of "abc", produces 97 (ASCII 'a')
GetByte(Bytes("abc"), Int(1)) # get the 1st byte of "abc", produces 98 (ASCII 'b')
GetByte(Bytes("abc"), Int(2)) # get the 2nd byte of "abc", produces 99 (ASCII 'c')
```

Additionally, the `SetByte` expression can modify individual bytes in byte strings. For example,

```SetByte(Bytes("base16", "0xff00"), Int(0), Int(0)) # set the 0th byte of 0xff00 to 0, produces 0x0000
SetByte(Bytes("base16", "0xff00"), Int(0), Int(128)) # set the 0th byte of 0xff00 to 128, produces 0x8000

SetByte(Bytes("abc"), Int(0), Int(98)) # set the 0th byte of "abc" to 98 (ASCII 'b'), produces "bbc"
SetByte(Bytes("abc"), Int(1), Int(66)) # set the 1st byte of "abc" to 66 (ASCII 'B'), produces "aBc"
```