#numbers #fractional #representation #textual #precision #base #95

base95

Textual representation of base 95 fractional numbers with arbitrary precision

2 releases

0.1.1 Jun 5, 2021
0.1.0 Jun 5, 2021

#1547 in Encoding

MIT license

11KB
198 lines

base95

Textual representation of base 95 fractional numbers with arbitrary precision, intended to be used in real-time collaborative applications.

Documentation

Example

use base95::Base95;
use std::str::FromStr;

fn main() {
    let n1 = Base95::mid();
    assert_eq!(n1.to_string(), "O");
    assert_eq!(n1.raw_digits(), vec![47]);

    let n2 = Base95::avg_with_zero(&n1);
    assert_eq!(n2.to_string(), "7");
    assert_eq!(n2.raw_digits(), vec![23]);

    let n3 = Base95::avg_with_one(&n1);
    assert_eq!(n3.to_string(), "g");
    assert_eq!(n3.raw_digits(), vec![71]);

    let n4 = Base95::avg(&n1, &n2);
    assert_eq!(n4.to_string(), "C");
    assert_eq!(n4.raw_digits(), vec![35]);

    let n5 = Base95::from_str("j>Z= 4").unwrap();
    assert_eq!(n5.raw_digits(), vec![74, 30, 58, 29, 0, 20]);
}

lib.rs:

Textual representation of base 95 fractional numbers with arbitrary precision, intended to be used in real-time collaborative applications.

It can only represent numbers between 0 and 1, exclusive. The leading 0. is omitted.

Heavily inspired by this article.

Why 95?

  • UTF-8, the most popular Unicode encoding scheme, can encode ASCII as is. (1 byte per character)
  • ASCII has 95 printable characters in total, from space to tilde.

Example

use base95::Base95;
use std::str::FromStr;

let n1 = Base95::mid();
assert_eq!(n1.to_string(), "O");
assert_eq!(n1.raw_digits(), vec![47]);

let n2 = Base95::avg_with_zero(&n1);
assert_eq!(n2.to_string(), "7");
assert_eq!(n2.raw_digits(), vec![23]);

let n3 = Base95::avg_with_one(&n1);
assert_eq!(n3.to_string(), "g");
assert_eq!(n3.raw_digits(), vec![71]);

let n4 = Base95::avg(&n1, &n2);
assert_eq!(n4.to_string(), "C");
assert_eq!(n4.raw_digits(), vec![35]);

let n5 = Base95::from_str("j>Z= 4").unwrap();
assert_eq!(n5.raw_digits(), vec![74, 30, 58, 29, 0, 20]);

Why is avg imprecise?

One of main considerations of this representation is storage efficiency of fractional index. So it is better to have a little imprecise, shorter string, than perfectly precise, longer string.

Of course, the result is deterministic, i.e., if the input is same, the output will always be same.

No runtime deps