bintols work with generic hmnsize

This commit is contained in:
Christoph J. Scherr 2023-09-20 18:16:21 +02:00
parent 12ac4ebb38
commit 3334920d18
5 changed files with 145 additions and 7 deletions

View File

@ -1,7 +1,9 @@
//* # See what's behind the datatypes of Rust
//*
//* This Crate shows off how datatypes of rust are stored in memory.
use crate::display::{bytes_to_bin, byte_bit_display};
// reexport macros
pub use crate::investigate_memory_layout;
/// ## Investigate the internal representation of variables
///
@ -9,9 +11,9 @@ use crate::display::{bytes_to_bin, byte_bit_display};
#[macro_export]
macro_rules! investigate_memory_layout {
($t:ty, $v:tt) => {
println!("Type:\t{}", type_name::<$t>());
println!("Type:\t{}", std::any::type_name::<$t>());
println!("\talign:\t{:?} B", std::mem::align_of::<$t>());
println!("\tID:\t{:?}\n", TypeId::of::<$t>());
println!("\tID:\t{:?}\n", std::any::TypeId::of::<$t>());
println!("\tItems:");
unsafe {
for (index, item) in $v.iter().enumerate() {
@ -28,10 +30,10 @@ macro_rules! investigate_memory_layout {
\t\tnote: \tmemory order reversed\n\
",
pointer,
byte_bit_display(std::mem::align_of_val(item)),
byte_bit_display(memory.len()),
display::byte_bit_display(std::mem::align_of_val(item)),
display::byte_bit_display(memory.len()),
memory,
bytes_to_bin(&memory)
display::bytes_to_bin(&memory)
);
}
}

View File

@ -1,5 +1,8 @@
//* # Tools that help display binary values, data sizes, etc
use super::*;
pub use num_traits::{PrimInt, ToPrimitive};
/// ## Get the binary representation for a Byte array [`&[u8]`]
///
/// ### Arguments
@ -18,5 +21,47 @@ pub fn bytes_to_bin(data: &[u8]) -> String {
/// Quickly format a number of Bytes [`usize`] with the corresponding
/// number of bits
pub fn byte_bit_display(data: usize) -> String {
format!("{:07} B = {:08} bit", data.clone(), data * 8)
format!("{} B = {} bit", data.clone(), data * 8)
}
/// ## Format total byte sizes to human readable sizes
pub fn humanbytes<T>(total: T) -> String
where
T: PrimInt,
T: ToPrimitive,
T: Ord,
T: std::fmt::Display,
T: std::fmt::Debug,
{
if total < T::from(KIBI).unwrap() {
return format!("{total} B");
} else if T::from(KIBI).unwrap() <= total && total < T::from(MEBI).unwrap() {
return format!("{:.2} K", total.to_f64().unwrap() / KIBI as f64);
} else if T::from(MEBI).unwrap() <= total && total < T::from(GIBI).unwrap() {
return format!("{:.2} M", total.to_f64().unwrap() / MEBI as f64);
} else if T::from(GIBI).unwrap() <= total && total < T::from(TEBI).unwrap() {
return format!("{:.2} G", total.to_f64().unwrap() / GIBI as f64);
} else if T::from(TEBI).unwrap() <= total && total < T::from(PEBI).unwrap() {
return format!("{:.2} T", total.to_f64().unwrap() / TEBI as f64);
} else if T::from(PEBI).unwrap() <= total && total < T::from(EXBI).unwrap() {
return format!("{:.2} P", total.to_f64().unwrap() / PEBI as f64);
}
// now we are starting to reach the sizes that are pretty unrealistic
// (as of 2023 that is, hello future)
//
// the later ones overflow `usize` on 64 Bit computers, so we have
// to work with a fixed, larger sized datatype
else {
let total: u128 = total.to_u128().unwrap();
if EXBI <= total && total < ZEBI {
return format!("{:.2} E", total.to_f64().unwrap() / EXBI as f64);
} else if ZEBI <= total && total < YOBI {
return format!("{:.2} Z", total.to_f64().unwrap() / ZEBI as f64);
} else if YOBI <= total {
return format!("{:.2} Y", total.to_f64().unwrap() / YOBI as f64);
}
else {
unreachable!()
}
}
}

View File

@ -1,3 +1,24 @@
//* # Tools to work with binary values, memory, storage
// official binary prefixes, see [https://en.wikipedia.org/wiki/Binary_prefix]
/// 2^10
pub const KIBI: usize = 2usize.pow(10);
/// 2^20
pub const MEBI: usize = 2usize.pow(20);
/// 2^30
pub const GIBI: usize = 2usize.pow(30);
/// 2^40
pub const TEBI: usize = 2usize.pow(40);
/// 2^50
pub const PEBI: usize = 2usize.pow(50);
/// 2^60
pub const EXBI: u128 = 2u128.pow(60);
// at this point, `usize` would overflow, so we have to switch to a bigger datatype.
/// 2^70
pub const ZEBI: u128 = 2u128.pow(70);
/// 2^80
pub const YOBI: u128 = 2u128.pow(80);
// use pt_core;
pub mod datalayout;
pub mod display;

View File

@ -0,0 +1,7 @@
use pt_bintols::*;
#[test]
fn mkdmp() {
let v = vec![true, true, false];
investigate_memory_layout!(bool, v);
}

View File

@ -0,0 +1,63 @@
use pt_bintols::*;
use pt_bintols::display::*;
#[test]
fn btobin() {
let data = [19, 19];
let r = bytes_to_bin(&data);
assert_eq!(r, format!("0b00010011_00010011"));
}
#[test]
fn big_btobin() {
let data = [12,31,82,32,123,32,92,23,12,32,12,1,1,1];
let r = bytes_to_bin(&data);
assert_eq!(r, format!("0b00001100_00011111_01010010_\
00100000_01111011_00100000_01011100_00010111_00001100\n\
_00100000_00001100_00000001_00000001_00000001"));
}
#[test]
fn bybit() {
assert_eq!(byte_bit_display(120), format!("120 B = 960 bit"));
assert_eq!(byte_bit_display(12), format!("12 B = 96 bit"));
assert_eq!(byte_bit_display(8), format!("8 B = 64 bit"));
}
#[test]
fn hmnbytes() {
assert_eq!(humanbytes(0), format!("0 B"));
assert_eq!(humanbytes(1), format!("1 B"));
assert_eq!(humanbytes(KIBI-1), format!("1023 B"));
assert_eq!(humanbytes(KIBI), format!("1.00 K"));
assert_eq!(humanbytes(KIBI+1), format!("1.00 K"));
assert_eq!(humanbytes(MEBI-1), format!("1024.00 K"));
assert_eq!(humanbytes(MEBI), format!("1.00 M"));
assert_eq!(humanbytes(MEBI+1), format!("1.00 M"));
assert_eq!(humanbytes(GIBI-1), format!("1024.00 M"));
assert_eq!(humanbytes(GIBI), format!("1.00 G"));
assert_eq!(humanbytes(GIBI+1), format!("1.00 G"));
assert_eq!(humanbytes(TEBI-1), format!("1024.00 G"));
assert_eq!(humanbytes(TEBI), format!("1.00 T"));
assert_eq!(humanbytes(TEBI+1), format!("1.00 T"));
assert_eq!(humanbytes(PEBI-1), format!("1024.00 T"));
assert_eq!(humanbytes(PEBI), format!("1.00 P"));
assert_eq!(humanbytes(PEBI+1), format!("1.00 P"));
assert_eq!(humanbytes(EXBI-1), format!("1024.00 P"));
assert_eq!(humanbytes(EXBI), format!("1.00 E"));
assert_eq!(humanbytes(EXBI+1), format!("1.00 E"));
assert_eq!(humanbytes(ZEBI-1), format!("1024.00 E"));
assert_eq!(humanbytes(ZEBI), format!("1.00 Z"));
assert_eq!(humanbytes(ZEBI+1), format!("1.00 Z"));
assert_eq!(humanbytes(YOBI-1), format!("1024.00 Z"));
assert_eq!(humanbytes(YOBI), format!("1.00 Y"));
assert_eq!(humanbytes(YOBI+1), format!("1.00 Y"));
}