Skip to content

Commit

Permalink
chore: document u128 feature (noir-lang#4225)
Browse files Browse the repository at this point in the history
# Description

## Problem\*

Resolves noir-lang#4142 

## Summary\*

Add documentation for U128

## Additional Context



## Documentation\*

Check one:
- [ ] No documentation needed.
- [X] Documentation included in this PR.
- [ ] **[Exceptional Case]** Documentation to be submitted in a separate
PR.

# PR Checklist\*

- [X] I have tested the changes locally.
- [X] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.

---------

Co-authored-by: kevaundray <[email protected]>
  • Loading branch information
guipublic and kevaundray authored Feb 6, 2024
1 parent e4378ee commit e5cfb4d
Showing 1 changed file with 49 additions and 0 deletions.
49 changes: 49 additions & 0 deletions docs/docs/noir/concepts/data_types/integers.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,55 @@ If you are using the default proving backend with Noir, both even (e.g. _u2_, _i

:::


## 128 bits Unsigned Integers

The built-in structure `U128` allows you to use 128-bit unsigned integers almost like a native integer type. However, there are some differences to keep in mind:
- You cannot cast between a native integer and `U128`
- There is a higher performance cost when using `U128`, compared to a native type.

Conversion between unsigned integer types and U128 are done through the use of `from_integer` and `to_integer` functions.

```rust
fn main() {
let x = U128::from_integer(23);
let y = U128::from_hex("0x7");
let z = x + y;
assert(z.to_integer() == 30);
}
```

`U128` is implemented with two 64 bits limbs, representing the low and high bits, which explains the performance cost. You should expect `U128` to be twice more costly for addition and four times more costly for multiplication.
You can construct a U128 from its limbs:
```rust
fn main(x: u64, y: u64) {
let x = U128::from_u64s_be(x,y);
assert(z.hi == x as Field);
assert(z.lo == y as Field);
}
```

Note that the limbs are stored as Field elements in order to avoid unnecessary conversions.
Apart from this, most operations will work as usual:

```rust
fn main(x: U128, y: U128) {
// multiplication
let c = x * y;
// addition and subtraction
let c = c - x + y;
// division
let c = x / y;
// bit operation;
let c = x & y | y;
// bit shift
let c = x << y;
// comparisons;
let c = x < y;
let c = x == y;
}
```

## Overflows

Computations that exceed the type boundaries will result in overflow errors. This happens with both signed and unsigned integers. For example, attempting to prove:
Expand Down

0 comments on commit e5cfb4d

Please sign in to comment.