#arithmetic-operations #optional #int #integer #wrapper #total #compare

oint

oint ('optional int') provides total operations on arithmetic

2 releases

0.1.1 Oct 5, 2023
0.1.0 Oct 5, 2023

#607 in Math

39 downloads per month

MIT/Apache

58KB
1K SLoC

oint

static analysis unit tests codecov

oint ('optional int') is a Rust crate that provides the integer types:

  • oi8, oi16, oi32, oi64, oi128, oisize,
  • ou8, ou16, ou32, ou64, ou128, ousize,

as wrappers for the types:

  • Option<i8>, etc.
  • Option<u8>, etc.

Arithmetic functions and operators are defined on oint types. Arithmetic on oint types are total functions. Computations that would traditionally overflow or panic instead return the None value. You can think of oint as a convenience around the checked_something() integer functions. oint is a library for the integers that enforces checked operations. From has been implemented to convert oint types to (and from) their Option representation.

PartialEq/Eq and PartialOrd/Ord are not implemented by design. The structural_eq method compares uses structural equality - the empty value is equal to itself. The indeterminate_eq method compares using NaN indeterminate equality - the empty value is not equal to itself.

Examples

fn factorial(n: ou8) -> ou8 {
    match *n {
        None => n,
        Some(0) => 1.into(),
        Some(_) => n * factorial(n - 1),
    }
}

palindrome example of integer overflow

use oint::indeterminate_eq;
use oint::ou8;

fn palindrome_overflow(x: u8) -> bool {
    let mut rev: u8 = 0;
    let mut temp: u8 = x;
    while temp != 0 {
        rev = (rev * 10) + (temp % 10);
        temp = temp / 10;
    }
    return x == rev;
}

fn palindrome_oint(x: u8) -> bool {
    let x: ou8 = x.into();
    let mut rev: ou8 = 0.into();
    let mut temp: ou8 = x;
    loop {
        match *temp {
            None => unreachable!(),
            Some(val) if val == 0 => break,
            Some(_) => {
                rev = (rev * 10) + (temp % 10);
                temp = temp / 10;
            }
        }
    }
    return indeterminate_eq!(rev, x);
}

fn main() {
    std::panic::set_hook(Box::new(|_| {}));
    let panics = std::panic::catch_unwind(|| {
        for val in u8::MIN..=u8::MAX {
            _ = palindrome_oint(val)
        }
    })
    .is_err();
    let _ = std::panic::take_hook();
    println!("Did palindrome_oint panic? {}", panics);

    std::panic::set_hook(Box::new(|_| {}));
    let panics = std::panic::catch_unwind(|| {
        for val in u8::MIN..=u8::MAX {
            _ = palindrome_overflow(val)
        }
    })
    .is_err();
    let _ = std::panic::take_hook();
    println!("Did palindrome_overflow panic? {}", panics);
}

No runtime deps