My original intention was to convert the signed primitive number to its hexadecimal representation in such a way as to preserve the sign of the number. It turns out that current implementations of LowerHex , UpperHex and siblings for signed primitive integers will simply treat them as unsigned. No matter what additional formatting flags I add, these implementations seem to simply reinterpret the number as its unsigned counterpart for formatting purposes. ( Playground )
println!("{:X}", 15i32); // F println!("{:X}", -15i32); // FFFFFFF1 (expected "-F") println!("{:X}", -0x80000000i32); // 80000000 (expected "-80000000") println!("{:+X}", -0x80000000i32); // +80000000 println!("{:+o}", -0x8000i16); // +100000 println!("{:+b}", -0x8000i16); // +1000000000000000
The documentation in std::fmt is unclear whether this should happen or even true, and UpperHex (or any other formatting character) does not mention that signed integer implementations interpret the numbers as unsigned. There seems to be no related issues in the Rust GitHub repository.
Ultimately, it would be possible to implement certain functions for the task (as shown below), and a failed flaw is not very compatible with the formatter API.
fn to_signed_hex(n: i32) -> String { if n < 0 { format!("-{:X}", -n) } else { format!("{:X}", n) } } assert_eq!(to_signed_hex(-15i32), "-F".to_string());
Is this behavior of signed signed types? Is there a way to do this formatting procedure while still sticking to the standard Formatter ?
source share