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

Move long usage guide from README to docs module #65

Merged
merged 4 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
335 changes: 0 additions & 335 deletions arbi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,341 +29,6 @@

- **Pure Rust** implementation.

## Usage

### Construct an `Arbi` integer

The following are equivalent and return an [`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html)
integer with value `0` (no memory allocation occurs):

- [`Arbi::new()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.new)
- [`Arbi::zero()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.zero)

`Arbi::default()` also returns zero, but it is not `const`.

```rust
use arbi::Arbi;

let a = Arbi::new();
let b = Arbi::default();
let c = Arbi::zero();

assert_eq!(a, 0);
assert_eq!(a, b);
assert_eq!(b, c);
```

Construct an [`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html) integer from any primitive integer type value,
any [`f64`](https://doc.rust-lang.org/nightly/core/primitive.f64.html) (except for infinities and NaNs), or any string containing a
base-`base` representation of an integer, where `base` must be in [2, 36].

```rust
use arbi::{base::DEC, Arbi};

// From any primitive integer type
let a = Arbi::from(u128::MAX);
assert_eq!(a, u128::MAX);

// From any f64 (except for infinities and NaNs)
let b = Arbi::from(f64::MAX);
assert_eq!(b, f64::MAX);

// From a string
let c = Arbi::from_str_radix("123456789", 10).unwrap();
let d = Arbi::from_str_base("123456789", DEC).unwrap();
assert_eq!(c, 123456789);
assert_eq!(c, d);

use core::str::FromStr;

// Currently, FromStr assumes base 10.
let e = Arbi::from_str("-987654321").unwrap();
assert_eq!(e, -987654321);
let f = "123456789".parse::<Arbi>().unwrap();
assert_eq!(f, 123456789);
```

Use [`Arbi::with_capacity_bits()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.with_capacity_bits) or [`Arbi::with_capacity()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.with_capacity) to construct an
integer representing zero with at least a specified capacity:
```rust
use arbi::{Arbi, Assign};

let mut a = Arbi::with_capacity_bits(128);
let initial_capacity = a.capacity_bits();

assert_eq!(a, 0);
assert!(initial_capacity >= 128);

a.assign(u128::MAX);

assert_eq!(a.capacity_bits(), initial_capacity); // no memory allocation needed
assert_eq!(a, u128::MAX);
```

### Assign to an `Arbi` integer

[`Assign`](https://docs.rs/arbi/latest/arbi/trait.Assign.html) to an [`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html) any primitive integer type value, a floating-point
value, a string, or another [`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html) integer.

The main benefit of assigning is that if there is already enough capacity,
memory allocation need not occur. In contrast, `from` methods typically involve
memory allocation.

```rust
use arbi::{Arbi, Assign};

let mut a = Arbi::with_capacity(10);
let mut capacity = a.capacity();

// From integer
a.assign(u128::MAX);
assert_eq!(a, u128::MAX);
assert_eq!(a.capacity(), capacity); // no memory allocation occurred

// From float
a.assign(f64::MAX);
assert_eq!(a, f64::MAX);
assert!(a.capacity() > capacity); // memory allocation occured because we needed
// more capacity to represent the value
capacity = a.capacity();

// From string (no need for the Assign trait)
if let Err(e) = a.assign_str_radix("123456789", 10) {
panic!("Parsing error: {}", e);
}
assert_eq!(a, 123456789);
assert_eq!(a.capacity(), capacity); // no memory allocation occurred

// From another Arbi integer
let b = Arbi::from(987654321);
a.assign(&b);
assert_eq!(a.capacity(), capacity); // no memory allocation occurred
```

### Comparisons

Compare an [`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html) to another [`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html), a primitive integer type value, or a
floating-point value.

All equality and comparison operators are supported `==`, `!=`, `<`, `<=`, `>`,
`>=`.

Comparisons with floating-point values are designed to be consistent with IEEE
754. See[`PartialOrd<f64> for Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#impl-PartialOrd%3Cf64%3E-for-Arbi) for a description of the semantics of
comparing an [`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html) to a floating-point value.

```rust
use arbi::{Arbi, Assign};

let mut a;

// Float
a = Arbi::one();
a <<= 2000_usize;

assert_ne!(a, f64::MAX);
assert!(a < f64::INFINITY);
assert!(a > f64::MAX);

// Integer
a.assign(u64::MAX);
assert_eq!(a, u64::MAX);
assert!(u128::MAX > a);
assert!(a > u32::MAX);

// Arbi
let b = Arbi::one();
assert!(a > b);
assert!(b < a);
```

### To and From a String

In what follows, `base` must be an integer in `[2, 36]`. Moreover, the
`*_radix()` and `*_base()` string-related functions are equivalent, except that
`*_radix()` functions panic on an invalid base and `*_base()` functions cannot
panic due to an invalid base.

Convert any [`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html) integer to a [`String`](https://doc.rust-lang.org/nightly/alloc/string/struct.String.html) containing the base-`base`
representation of the integer.
- [`Arbi::to_string_radix()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.to_string_radix)
- [`Arbi::to_string_base()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.to_string_base)
- `Arbi::to_string()` (uses `Arbi::to_string_base()`, assuming base `10`).

Convert any string containing the base-`base` representation of an integer to
an [`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html).
- [`Arbi::from_str_radix()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.from_str_radix)
- [`Arbi::from_str_base()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.from_str_base)
- `Arbi::from_str()` (same as `from_str_base()` but assumes base `10` and
needs `core::str::FromStr` in scope).

Assign any string containing the base-`base` representation of an integer to
an [`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html).
- [`Arbi::assign_str_radix()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.assign_str_radix)
- [`Arbi::assign_str_base()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.assign_str_base)

```rust
use arbi::{base::OCT, Arbi};
use core::str::FromStr; // needed for from_str() alone

let mut a = Arbi::from(u128::MAX);

// To string
assert_eq!(a.to_string(), u128::MAX.to_string()); // assumes base-10
assert_eq!(a.to_string_radix(16), "ffffffffffffffffffffffffffffffff");
assert_eq!(
a.to_string_base(OCT),
"3777777777777777777777777777777777777777777"
);

// From string
assert_eq!(
Arbi::from_str("340282366920938463463374607431768211455").unwrap(),
u128::MAX
); // assumes base-10
assert_eq!(
Arbi::from_str_radix("ffffffffffffffffffffffffffffffff", 16).unwrap(),
u128::MAX
);
assert_eq!(
Arbi::from_str_base("3777777777777777777777777777777777777777777", OCT)
.unwrap(),
u128::MAX
);

// Assign string
a.assign_str_radix("573c0ff2cce44d2025e04db43", 16);
assert_eq!(a, 0x573c0ff2cce44d2025e04db43_u128);

a.assign_str_base("1772555052337322416757226463207030", OCT);
assert_eq!(a, 0o1772555052337322416757226463207030_u128);
```

### Arithmetic

All standard arithmetic operations are implemented:
- Binary operators: `+`, `-`, `*`, `/`, `%`, `+=`, `-=`, `*=`, `/=`, `%=`
- Unary operators: `-`.

### Bitwise Operations

All standard bitwise operations are implemented. These operators perform bitwise
operations on integers using two's complement representation (with sign
extension).
- Shift operators: `<<`, `>>`, `<<=`, `>>=`.
- Bitwise complement: `!`.
- Bitwise AND, OR, and XOR: `&`, `|`, `^`, `&=`, `|=`, `^=`.

Test, set, clear, or invert (i.e. toggle) a bit at a specified index on the
two's complement representation (with sign extension) of an
[`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html) integer:
- [`Arbi::test_bit()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.test_bit)
- [`Arbi::set_bit()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.set_bit)
- [`Arbi::clear_bit()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.clear_bit)
- [`Arbi::invert_bit()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.invert_bit)

Obtain the number of bits needed to represent the absolute value of an [`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html)
integer using [`Arbi::size_bits()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.size_bits):

```rust
use arbi::Arbi;
let mut a = Arbi::zero();
assert_eq!(a.size_bits(), 0);
a.incr(); // 1
assert_eq!(a.size_bits(), 1);
a.incr(); // 10
assert_eq!(a.size_bits(), 2);
a.incr(); // 11
assert_eq!(a.size_bits(), 2);
```

### To Built-In Integer

In what follows, let `*` denote any primitive integer type name:
`i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize`.

Methods
- `wrapping_to_*()`: convert this [`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html) integer to a primitive integer type value.
This is “wrapping”.

See [`Arbi::wrapping_to_i32()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.wrapping_to_i32).

- `checked_to_*()`: try to convert this [`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html) integer to a primitive integer
type value. If this [`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html) integer does not fit in the target primitive
integer type, returns `None`.

See [`Arbi::checked_to_i32()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.checked_to_i32).

- `fits_*()`: test if this [`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html) integer fits in a primitive integer type.
The [`Fits`](https://docs.rs/arbi/latest/arbi/trait.Fits.html) trait can also be used to do the same thing.

See [`Arbi::fits_i32()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.fits_i32) and also the [`Fits`](https://docs.rs/arbi/latest/arbi/trait.Fits.html) trait.

### To Floating-Point Value

Convert an [`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html) integer to a floating-point value using the [`Arbi::to_f64()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.to_f64)
method:

```rust
use arbi::{Arbi, Pow};

let a = Arbi::from(-987654321);
assert_eq!(a.to_f64(), -987654321.0);

let b = Arbi::from(1_u64 << 32);
assert_ne!((&b).pow(31_usize).to_f64(), f64::INFINITY);
assert_eq!((&b).pow(32_usize).to_f64(), f64::INFINITY);
```

### Increment/Decrement

Increment or decrement an [`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html) integer in-place by one using the
[`Arbi::incr()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.incr) and [`Arbi::decr()`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html#method.decr) methods (`+=` and `-=` can also be used).

```rust
use arbi::Arbi;

let mut a = Arbi::zero();

a.incr();
assert_eq!(a, 1);

a.decr();
assert_eq!(a, 0);

a.decr();
assert_eq!(a, -1);
```

### Exponentiation

Raise an [`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html) integer to the power of a [`usize`](https://doc.rust-lang.org/nightly/core/primitive.usize.html), [`u128`](https://doc.rust-lang.org/nightly/core/primitive.u128.html), or another
[`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html) integer using the [`Pow`](https://docs.rs/arbi/latest/arbi/trait.Pow.html) trait.

```rust
use arbi::{Arbi, Pow};

let mut a = Arbi::from(2);
a = a.pow(128_usize);
assert_eq!(
a,
Arbi::from_str_radix("100000000000000000000000000000000", 16).unwrap()
);
```

### Display

The [`core::fmt::Display`](https://doc.rust-lang.org/nightly/core/fmt/trait.Display.html) implementation uses the base-10 representation of the
[`Arbi`](https://docs.rs/arbi/latest/arbi/struct.Arbi.html) integer and by extension, so does `Arbi::to_string()`.

```rust
use arbi::Arbi;

let a = Arbi::from(12345);
assert_eq!(format!("{}", a), "12345");
assert_eq!(a.to_string(), "12345");
```

## License

This project is dual-licensed under either the [Apache License, Version 2.0](https://github.com/OTheDev/arbi/blob/main/LICENSE-APACHE)
Expand Down
9 changes: 5 additions & 4 deletions arbi/src/doc.rs → arbi/src/docs/algorithms.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
//! Extended documentation.
//!
//! Currently, this only includes notes on some of the algorithms used.
/*
Copyright 2024-2025 Owain Davies
SPDX-License-Identifier: Apache-2.0 OR MIT
*/

//! # Algorithms
//! Includes notes on some of the algorithms employed.

//! ## Addition
//! Knuth Algorithm A (Vol. 2, 4.3.1, p. 266)
Expand Down
10 changes: 10 additions & 0 deletions arbi/src/docs/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
Copyright 2024-2025 Owain Davies
SPDX-License-Identifier: Apache-2.0 OR MIT
*/

//! Extended documentation.

#[cfg(not(doctest))]
pub mod algorithms;
pub mod tour;
Loading
Loading