如何将有符号整数格式化为符号可识别的十六进制表示? [英] How do I format a signed integer to a sign-aware hexadecimal representation?

查看:320
本文介绍了如何将有符号整数格式化为符号可识别的十六进制表示?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的初衷是将签名的原始数字转换为其十六进制表示,以保留数字的符号。事实证明, LowerHex UpperHex 的当前实现以及已签名的原始整数的亲属将简单地将它们视为无符号。无论我添加哪些额外的格式化标记,这些实现似乎只是为了格式化目的而将数字重新解释为其无符号对应物。 (游乐场

My initial intent was to convert a signed primitive number to its hexadecimal representation in a way that preserves the number's sign. It turns out that the current implementations of LowerHex, UpperHex and relatives for signed primitive integers will simply treat them as unsigned. Regardless of what extra formatting flags that I add, these implementations appear 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

std :: fmt 目前尚不清楚是否应该这样做发生,甚至有效,并 UpperHex (或任何其他格式特征)未提及有符号整数的实现将数字解释为无符号。 Rust的GitHub存储库似乎也没有任何相关问题。

The documentation in std::fmt is not clear on whether this is supposed to happen, or is even valid, and UpperHex (or any other formatting trait) does not mention that the implementations for signed integers interpret the numbers as unsigned. There seem to be no related issues on Rust's GitHub repository either.

最终,可以为任务实现特定的功能(如下所示),不幸的是不存在与格式化程序API非常兼容。

Ultimately, one could implement specific functions for the task (as below), with the unfortunate downside of not being 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());

有意的有符号整数类型的这种行为是什么?有没有办法在遵循标准 Formatter

Is this behaviour for signed integer types intentional? Is there a way to do this formatting procedure while still adhering to a standard Formatter?

推荐答案


有没有办法在遵守标准的情况下执行此格式化过程 格式化程序

是的,但是你需要创建一个newtype以提供 UpperHex 的独特实现。这是一个尊重 + 0 的实现标志(可能还有更多,我还没有测试过):

Yes, but you need to make a newtype in order to provide a distinct implementation of UpperHex. Here's an implementation that respects the +, # and 0 flags (and possibly more, I haven't tested):

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

struct ReallySigned(i32);

impl UpperHex for ReallySigned {
    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 >= 0, prefix, &bare_hex)
    }
}

fn main() {
    for &v in &[15, -15] {
        for &v in &[&v as &UpperHex, &ReallySigned(v) as &UpperHex] {
            println!("Value: {:X}", v);
            println!("Value: {:08X}", v);
            println!("Value: {:+08X}", v);
            println!("Value: {:#08X}", v);
            println!("Value: {:+#08X}", v);
            println!();
        }
    }
}

这篇关于如何将有符号整数格式化为符号可识别的十六进制表示?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆