How to format a negative hex number in alternate form

  • LowerHex apparently prints negative numbers in twos complement form
  • Adding a sign is still possible even though it always prints a positive number?

I expected the following to print -0x00ab, but instead it prints +0xff55

let num: i16 = -0xab;
println!("{num:+#07x}")

Is the only way to manually check the sign before formatting?

It seems that you need to use the NewType pattern to implement either the LowerHex or the UpperHex formatter traits (or both).

I'll quote the relevant part here

use std::fmt::{self, Formatter, UpperHex};
use num_traits::Signed;

struct ReallySigned<T: PartialOrd + Signed + UpperHex>(T);

impl<T: PartialOrd + Signed + UpperHex> UpperHex for ReallySigned<T> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        let prefix = if f.alternate() { "0x" } else { "" };
        let bare_hex = format!("{:X}", self.0.abs());
        f.pad_integral(self.0 >= T::zero(), prefix, &bare_hex)
    }
}

fn main() {
    println!("{:#X}", -0x12345678);
    println!("{:#X}", ReallySigned(-0x12345678));
}

Playground

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.