Integer Arithmetic & Casting

All arithmetic is checked: overflow and division by zero cause the transaction to abort, rolling back all changes.

8.1 Operators

result underflows (below 0) integer division (truncates) shift amount ≥ bit width (bits shifted out are lost, no abort for that) shift amount ≥ bit width

All arithmetic is checked: overflow and division by zero cause the transaction to abort, rolling back all changes. There is no wrapping arithmetic and no unary minus.

8.2 Type inference and suffixes

let a = 10;          // inferred from use; defaults to u64
let b: u8 = 10;      // annotation
let c = 10u128;      // suffix
let d = 1_000_000;   // underscores allowed
let e = 0xFF;        // hex
// let bad = a + b;  // ERROR: u64 + u8 — no implicit conversion

8.3 Casting with as

Casting is explicit and checked. Parentheses around (e as T) were required in older Move; Move 2024 and Move 2 relax this in many positions, but parentheses remain good style.

let x: u8 = 200;
let y: u64 = (x as u64);            // widening: always succeeds
let z: u8 = (300u64 as u8);         // ABORT: value does not fit
let w = (x as u256) * 1000;         // widen before multiplying to avoid overflow

8.4 Safe math patterns

/// Multiply then divide without intermediate overflow: (a * b) / c
public fun mul_div(a: u64, b: u64, c: u64): u64 {
    (((a as u128) * (b as u128)) / (c as u128)) as u64
}

/// Saturating subtraction
public fun sat_sub(a: u64, b: u64): u64 {
    if (a > b) a - b else 0
}

8.5 Standard integer helpers

Functions (examples) Sui std::u64 (and u8..u256) max, min, diff, pow, sqrt, divide_and_round_up, to_string, try_as_u8/try_as_u16/try_as_u32, macros do!, range_do! Aptos aptos_std::math64 / math128

max, min, average, pow, sqrt, mul_div, log2, ceil_div

Aptos aptos_std::fixed_point64, math_fixed64 Legacy fixed-point (both chains)

// Sui (method syntax on primitives works in Move 2024)
let m = 7u64.max(9);       // 9
let p = 2u64.pow(10);      // 1024
let s = 1000u64.to_string();