Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integer and boolean type introduction & about #66

Merged
merged 10 commits into from
Jul 12, 2024
4 changes: 2 additions & 2 deletions concepts/booleans/.meta/config.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"blurb": "<todo>",
"blurb": "As in most other programming languages, a Boolean type in Cairo has two possible values: true and false.",
"authors": [
"misicnenad"
"rajeebkm"
],
"contributors": []
}
50 changes: 50 additions & 0 deletions concepts/booleans/about.md
Original file line number Diff line number Diff line change
@@ -1 +1,51 @@
# The Boolean Type

In Cairo, the Boolean type is essential for logical operations and conditional statements. Booleans in Cairo are one `felt252` in size, ensuring efficient use of space while maintaining the simplicity of true/false logic.

The Boolean type in Cairo is specified using the keyword `bool`. This enables the declaration and manipulation of Boolean variables within the language. For instance, consider the following example:

```rust
fn main() {
let t = true;

let f: bool = false; // with explicit type annotation
}
```

In this example, two Boolean variables are declared. The variable `t` is assigned the value `true` and declared as a boolean type implicitly, while the variable `f` is explicitly annotated with the `bool` type and assigned the value `false`.

One important aspect to note is that when declaring a boolean variable in Cairo, it is mandatory to use either the `true` or `false` literals as the value. This means that integer literals, such as `0` or `1`, cannot be used as substitutes for `false` or `true`. The strict enforcement of this rule ensures type safety and prevents potential logical errors in smart contract development.


The following code snippet demonstrates how to use boolean types in Cairo. It shows the declaration of boolean variables, assignment of boolean expressions, and usage of assertions to verify the correctness of the boolean logic.

## Boolean Operators in Cairo
- `||` (logical OR): Returns `true` if at least one of the operands is `true`.
- `&&` (logical AND): Returns `true` if both operands are `true`.
- `!` (logical NOT): Returns the opposite Boolean value of the operand.

## Example Code
```rust
rajeebkm marked this conversation as resolved.
Show resolved Hide resolved
fn main() {
// Declaration of Boolean variables
let t: bool = true;
let f: bool = false;

// Boolean expression evaluation
let true_expr = 5 == 5; // true
let false_expr = 7 == 5; // false

// Using Boolean operators
let or_expr = t || f; // true || false => true
let and_expr = t && f; // true && false => false
let not_expr = !f; // !false => true

// Assertions to verify the correctness
assert(t == true_expr, 'this is true'); // t == true
rajeebkm marked this conversation as resolved.
Show resolved Hide resolved
assert(f == false_expr, 'this is false'); // f == false
assert(or_expr == true, 'this is true for OR'); // true
assert(and_expr == false, 'this is false for AND'); // false
assert(not_expr == true, 'this is true for NOT'); // true
}
```

4 changes: 4 additions & 0 deletions concepts/booleans/introduction.md
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
# Introduction

In Cairo, similar to most other programming languages, the Boolean type represents a binary state with two possible values: `true` and `false`.

This allows developers to implement logical conditions and control structures efficiently, enabling robust and dynamic smart contract development.
7 changes: 6 additions & 1 deletion concepts/booleans/links.json
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
[]
[
{
"url": "https://book.cairo-lang.org/ch02-02-data-types.html#the-boolean-type",
"description": "Boolean type in the Cairo book"
}
]
4 changes: 2 additions & 2 deletions concepts/felts/.meta/config.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"blurb": "<todo>",
"blurb": "In Cairo, variables and arguments default to field elements, indicated by the keyword felt252 if not specified otherwise",
"authors": [
"misicnenad"
"rajeebkm"
],
"contributors": []
}
23 changes: 23 additions & 0 deletions concepts/felts/about.md
Original file line number Diff line number Diff line change
@@ -1 +1,24 @@
# Felt Type

## Felt Type

In Cairo, the default type for a variable or argument, if not explicitly specified, is a **felt**, also called a **field element**. This is one of the [scalar types](https://book.cairo-lang.org/ch02-02-data-types.html#scalar-types) represented by the keyword `felt252`. A field element is an integer within the range $0 ≤ x < P$, where $P$ is a very large prime number currently equal to $2^{251} + 17 \cdot 2^{192} + 1$.

## Arithmetic Operations

When performing arithmetic operations (addition, subtraction, multiplication) with field elements, if the result falls outside the range of the prime number $P$, an overflow or underflow occurs.

To handle this, Cairo adjusts the result by adding or subtracting an appropriate multiple of $P$ to bring the result back within the valid range. Essentially, this means the result is computed modulo $P$.

## Division in Cairo

A critical distinction between integers and field elements is how division is handled. Unlike regular CPU integer division, where the result of $x$ divided by $y$ is defined as the integer part of the quotient (returning the floor value), Cairo ensures that the division of field elements always satisfies the equation:

$\frac{x}{y} \cdot y = x$

This means:
- If $y$ divides $x$ as integers, Cairo will provide the expected result. For instance, $\frac{6}{2}$ will yield $3$.
- If $y$ does not divide $x$ , the result can be surprising. For example, since $2 \cdot \left(\frac{P+1}{2}\right) = P + 1 \equiv 1 \mod P$, the value of $\frac{1}{2}$ in Cairo is $\frac{P + 1}{2}$ (not $0$ or $0.5$), as it satisfies the above equation:


Understanding these nuances in field element operations is crucial when working with Cairo, especially when dealing with division and ensuring your calculations remain within the valid range defined by the prime number $P$ .
11 changes: 11 additions & 0 deletions concepts/felts/introduction.md
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
# Introduction

Felt is one of the scalar types in Cairo, just like integers and booleans, and is represented by the keyword `felt252`. `felt252` is a fundamental data type in Cairo from which all other data types are derived. `felt252` can also be used to store [short string representations](https://starknet-by-example.voyager.online/getting-started/basics/bytearrays-strings.html#short-strings) with a maximum length of 31 characters.

For example:

```rust
let felt: felt252 = 100;
let felt_as_str: felt252 = 'Hello Starknet!';

let _felt = felt + felt_as_str;
```
4 changes: 2 additions & 2 deletions concepts/integers/.meta/config.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"blurb": "<todo>",
"blurb": "In Cairo, an Integer is a number and a scalar type, like felt252 and booleans, with felt252 serving as the foundational type for all other types in the core library.",
"authors": [
"misicnenad"
"rajeebkm"
],
"contributors": []
}
104 changes: 104 additions & 0 deletions concepts/integers/about.md
Original file line number Diff line number Diff line change
@@ -1 +1,105 @@
# Integer Types

An `integer` is a number without a fractional component. In Cairo, the type declaration for integers indicates the number of bits the programmer can use to store the value. Table 1 outlines the built-in integer types in Cairo, each with a specific size:

| Length | Unsigned |
|----------|----------|
| 8-bit | u8 |
| 16-bit | u16 |
| 32-bit | u32 |
| 64-bit | u64 |
| 128-bit | u128 |
| 256-bit | u256 |
| 32-bit | usize |

**Table 1: Integer Types in Cairo**

## Details

Each integer variant in Cairo has an explicit size. These variants can be used to declare the type of an integer value based on the required storage size.

- **u8**: 8-bit unsigned integer.
- **u16**: 16-bit unsigned integer.
- **u32**: 32-bit unsigned integer.
- **u64**: 64-bit unsigned integer.
- **u128**: 128-bit unsigned integer.
- **u256**: 256-bit unsigned integer.
- **usize**: 32-bit unsigned integer (currently an alias for u32).

The `usize` type is particularly noteworthy. Although it is currently an alias for `u32`, it might play a more distinct role in the future, especially if Cairo can be compiled to MLIR (Multi-Level Intermediate Representation).

## Constraints

As these variables are unsigned, they cannot represent negative numbers. This restriction ensures that all values are non-negative, which can be beneficial in certain programming contexts, such as array indexing and memory management.

By understanding and utilizing these integer types, Cairo programmers can better manage memory and optimize performance for their specific use cases.

This code will cause the program to panic:

```rust
fn sub_u8s(x: u8, y: u8) -> u8 {
x - y
}

fn main() {
sub_u8s(1, 3);
}
```
All integer types mentioned previously fit into a `felt252`, except for `u256`, which needs 4 more bits to be stored. Under the hood, `u256` is essentially a struct with 2 fields:

```rust
struct u256 {
low: u128,
high: u128
}
```

## Cairo's Support for Signed Integers

Cairo also provides support for signed integers, starting with the prefix `i`. These integers can represent both positive and negative values, with sizes ranging from `i8` to `i128`. Each signed variant can store numbers from $-2^{n-1}$ to $2^{n-1} - 1$ inclusive, where $n$ is the number of bits that variant uses.

For example, an `i8` can store numbers from $-2^7$ to $2^7 - 1$, which equals $-128$ to $127$.

## Integer Literals in Cairo

You can write integer literals in any of the forms shown in Table 2. Note that number literals that can be multiple numeric types allow a type suffix, such as `57_u8`, to designate the type. It is also possible to use a visual separator `_` for number literals, in order to improve code readability.


| Numeric Literals | Example |
| ---------------- | ------- |
| Decimal | 98222 |
| Hex | 0xff |
| Octal | 0o04321 |
| Binary | 0b01 |

**Table 2: Integer Literals in Cairo.**

So how do you know which type of integer to use? Try to estimate the max value your int can have and choose the appropriate size. The primary situation in which you’d use `usize` is when indexing some sort of collection.

## Numeric Operations

Cairo supports the basic mathematical operations you’d expect for all the integer types: addition, subtraction, multiplication, division, and remainder. Integer division truncates toward zero to the nearest integer. The following code shows how you’d use each numeric operation in a `let` statement:

```rust
fn main() {
// addition
let sum = 5_u128 + 10_u128;

// subtraction
let difference = 95_u128 - 4_u128;

// multiplication
let product = 4_u128 * 30_u128;

// division
let quotient = 56_u128 / 32_u128; // result is 1
let quotient = 64_u128 / 32_u128; // result is 2

// remainder
let remainder = 43_u128 % 5_u128; // result is 3
}
```

Each expression in these statements uses a mathematical operator and evaluates to a single value, which is then bound to a variable.

List of all operators that Cairo provides can be found [here](https://book.cairo-lang.org/appendix-02-operators-and-symbols.html#operators)
4 changes: 4 additions & 0 deletions concepts/integers/introduction.md
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
# Introduction

`Integer` is one of the scalar types in Cairo, just like felt252 and booleans. The `felt252` type is a fundamental type in the core library, serving as the foundation for creating all other types in the core library.

However, for added safety, it's best to use integer types instead of `felt252` whenever you can. Integer types have built-in security features that help protect your code from common issues like overflow and underflow errors. Using these safer integer types makes your programs more secure and less vulnerable to attacks or other security risks.
7 changes: 6 additions & 1 deletion concepts/integers/links.json
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
[]
[
{
"url": "https://book.cairo-lang.org/ch02-02-data-types.html#integer-types",
"description": "Integer type in the Cairo book"
}
]
Loading