How to use num crate in Rust numeric types

The `num` crate provides a unified set of numeric traits and types that extend Rust's standard library, allowing you to write generic code that works across integers, floats, and complex numbers.

The num crate provides a unified set of numeric traits and types that extend Rust's standard library, allowing you to write generic code that works across integers, floats, and complex numbers. You primarily use the num_traits crate for traits like ToPrimitive and Zero, and the num crate itself for specific types like BigInt or Complex.

Add the dependencies to your Cargo.toml:

[dependencies]
num = "0.4"
num-traits = "0.2"

For generic arithmetic, import the relevant traits from num_traits and constrain your type parameters. This lets you write functions that accept any numeric type supporting the operation, rather than hardcoding i32 or f64.

use num_traits::{Zero, One, ToPrimitive};

fn calculate_sum<T>(a: T, b: T) -> T 
where
    T: Zero + One + std::ops::Add<Output = T>,
{
    a + b
}

fn main() {
    // Works with standard types
    let int_sum = calculate_sum(10i32, 5i32);
    
    // Works with floats
    let float_sum = calculate_sum(10.5f64, 2.5f64);
    
    // Convert to primitive if needed
    if let Some(val) = int_sum.to_f64() {
        println!("Converted to f64: {}", val);
    }
}

When you need types beyond standard limits, such as arbitrary-precision integers or complex numbers, use the concrete types provided by the num crate. BigInt and BigUint handle numbers of any size, while Complex supports mathematical operations on complex numbers.

use num::BigInt;
use num::Complex;

fn main() {
    // Arbitrary precision integer
    let big_num = BigInt::from(1000000000000000000000000000000u128);
    let result = big_num * big_num;
    println!("Big integer result: {}", result);

    // Complex number arithmetic
    let c1 = Complex::new(1.0, 2.0);
    let c2 = Complex::new(3.0, 4.0);
    let c_sum = c1 + c2;
    println!("Complex sum: {}", c_sum);
}

Remember that num_traits is a dependency of num, so importing num often pulls in the traits, but explicitly importing num_traits is clearer for generic code. This setup ensures your numeric logic remains flexible and type-safe without sacrificing performance for standard types.