# Math

Generally, all types that are usable in o1js are also usable out-of-the-box in protokit.
But there are some caveats to dealing with bounded integers (`UInt64`

, `UInt32`

).

## Integers

By default, o1js exposes two classes `UInt64`

and `UInt32`

to protect you from overflows that can happen
if you use `Field`

directly.
Unfortunately, these don't work well with Protokit since they use the hard-failing o1js assertions instead of the protokit-specific `assert`

.
This leads to your application being non-complete and being unable to include failed transactions in settlements.

To overcome this, we created a number of classes in `@proto-kit/library`

that handle all of that for you while providing the same interface as the vanilla variants.

`UInt32`

`UInt64`

`UInt112`

`UInt224`

In addition to the methods known from o1js, we implement the `sqrtMod()`

and `sqrtFloor()`

functions to help facilitate square-root calculations.

Make sure to import from `@proto-kit/library`

when using `UInt32`

and `UInt64`

### Creating protokit UInts

There are multiple ways of creating UInts, each of them with their own properties.
This example uses `UInt64`

, but can be used with any other UInt the same way.

The most straight forward one is using `UInt64.from()`

. This accepts `UInt64 | string | bigint | number`

.
It should be used for creation of a constant or for copying a existing UInt.

```
// Using string
const uint1 = UInt64.from("5");
// Using number
const uint2 = UInt64.from(5);
// Using another UInt64
const uint3 = UInt64.from(uint1);
```

To convert a Field into a UInt, you can use both the `Safe`

and `Unsafe`

`fromField()`

function.

```
// Creates a UInt64 and performs necessary range checks on the given `field`
UInt64.Safe.fromField(field);
// Creates a UInt64 without performing range checks.
// This safes constraints, but relies on the given field to be ensured to be in range
UInt64.Unsafe.fromField(Field(1));
```

Because range checks (which are used under the hood to enable the safety of UInts) are very expensive, these different methods of creating and transforming UInts are a way for developers to optimize and decrease proving effort.

### Transforming UInts

Sometimes we need to go from a specific UInt bit-range to a different one. Let's say we want to go from UInt32 to UInt64 and back.

The upward direction is trivial and will not generate additional constraints

`const uint64 = UInt64.Unsafe.fromField(uint32.value);`

Going down to UInt32 again, we need to range-check the 64-bit number to ensure it is within 32-bits.
Therefore, we need to use the `Safe.fromField`

method.

`const uint32 = UInt32.Safe.fromField(uint64.value);`

For some UInts, simpler conversion functions exist.

`UInt32.toUInt64()`

`UInt112.toUInt224()`

### Converting to o1js UInt64

Every UInt from the `@proto-kit/library`

package also has a conversion function to turn it into a `o1js`

UInt64

```
// Will fail the transaction if the value of uint exceeds 64 bits
const o1jsUint = uint.toO1UInt64()
// If the value of `uint` exceeds 64 bits, it will take the maximum value fitting into 64 bits
const o1jsUint2 = uint.toO1UInt64Clamped()
```