Skip to content

Instantly share code, notes, and snippets.

@Roms1383
Created January 9, 2024 04:35
Show Gist options
  • Save Roms1383/90deba2fc2e3e2352389adca76934f4f to your computer and use it in GitHub Desktop.
Save Roms1383/90deba2fc2e3e2352389adca76934f4f to your computer and use it in GitHub Desktop.
High and low bits concatenation in bitflags context
trait SetBytes {
fn set_low(&mut self, value: u32);
fn set_high(&mut self, value: u32);
}
trait FullBytes {
fn convert(&mut self) -> u32;
}
impl SetBytes for u64 {
fn set_low(&mut self, value: u32) {
*self &= !0xFFFFFFFF;
*self |= value as u64;
}
fn set_high(&mut self, value: u32) {
*self &= !0xFFFFFFFF00000000;
*self |= (value as u64) << 32;
}
}
impl FullBytes for u32 {
fn convert(&mut self) -> u32 {
u32::from_str_radix(&format!("{:0<32b}", *self), 2).unwrap()
}
}
fn main() {
general();
println!("\n\n");
bitflags();
println!("\n\n");
convert();
}
fn dashes() {
println!("{}",String::from_utf8(vec![b'-'; 64 + 20 + 2 + 1]).unwrap());
}
fn general() {
println!("general case\n");
let hi = 0x01234567_u32;
let lo = 0x89abcdef_u32;
println!("({hi:·<20}) {hi:0<64b}");
println!("({lo:·>20}) {lo:0>64b}");
let mut combined = 0_u64;
combined.set_high(hi);
combined.set_low(lo);
assert_eq!(combined, 0x01234567_89abcdef);
dashes();
println!("({combined:·>20}) {combined:064b}");
println!("🚫 note how it's valid yet unappropriate for bitflags usage");
println!("because 0x01234567 as u32 is {hi:b} (25 bits long)");
}
fn bitflags() {
println!("another test for bitflags\n");
let hi = 0x91A2B380_u32;
let lo = 0x89abcdef_u32;
println!("({hi:·<20}) {hi:0<64b}");
println!("({lo:·>20}) {lo:0>64b}");
let mut combined = 0_u64;
combined.set_high(hi);
combined.set_low(lo);
assert_eq!(combined, 0x91A2B380_89abcdef);
dashes();
println!("({combined:·>20}) {combined:064b}");
println!("✅ note how it's both valid and appropriate to use with bitflags :)");
println!("because 0x91A2B380 as u32 is {hi:b} (32 bits long)");
}
fn convert() {
println!("convert number to full-length bits");
let mut smaller = 0x01234567_u32;
let fit = smaller.convert();
println!("before: {smaller:b}");
println!("after : {fit:b}");
}
@Roms1383
Copy link
Author

Roms1383 commented Jan 9, 2024

Permalink to the playground.

Output:

general case

(19088743············) 1001000110100010101100111000000000000000000000000000000000000000
(··········2309737967) 0000000000000000000000000000000010001001101010111100110111101111
---------------------------------------------------------------------------------------
(···81985529216486895) 0000000100100011010001010110011110001001101010111100110111101111
🚫 note how it's valid yet unappropriate for bitflags usage
because 0x01234567 as u32 is 1001000110100010101100111 (25 bits long)



another test for bitflags

(2443359104··········) 1001000110100010101100111000000000000000000000000000000000000000
(··········2309737967) 0000000000000000000000000000000010001001101010111100110111101111
---------------------------------------------------------------------------------------
(10494147446373600751) 1001000110100010101100111000000010001001101010111100110111101111
✅ note how it's both valid and appropriate to use with bitflags :)
because 0x91A2B380 as u32 is 10010001101000101011001110000000 (32 bits long)



convert number to full-length bits
before: 1001000110100010101100111
after : 10010001101000101011001110000000

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment