在 c++ 中将长整型转换为十六进制和二进制

Convert long long into Hex and Binary in c++

本文关键字:十六进制 二进制 转换 长整型 c++      更新时间:2023-10-16

我有这个代码:

char digits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
    'C', 'D', 'E', 'F' };
string toFormatFromDecimal(long long t, Format format) {
    int digitCount = ceil(log(t) / log((int) format));
    string hex = "";
    for (int i = 0; i < digitCount; i++) {
        hex += digits[(int) (t%format)];
        t = t/format;
    }        
    return string(hex.rbegin(), hex.rend());
}
string toHexFromDecimal(long long t) {
        return "0x" + toFormatFromDecimal(t, HEX);
}
string toBinFromDecimal(long long t) {
    return toFormatFromDecimal(t, BIN);
}

应该将长整型转换为十六进制或二进制表示,这适用于所有正数,但不适用于负数。

任何想法如何扩展我的代码来处理有符号数字?谢谢弗洛里安

编辑:现在我在这里有一个类似的问题(字符串 ->长)

要转换有符号值,只需将输入转换为 unsigned long long . 除此之外:你不需要建立数字计数,一旦你处理一个未签名的人整体类型,只要继续直到它0. 并确保即使原始值0,您至少会得到一位数字,使用do ... while循环:

std::string results;
unsigned long long tmp = t;
do
{
    results += digits[ tmp % format ];
    tmp /= format;
} while ( tmp != 0 );
std::reverse( results.begin(), results.end() );
return results;

通常更好的解决方案是传递最少的位数在作为参数:

std::string
toString( unsigned long long value, int base, int minSize = 1 )
{
    static char const digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    assert( base >= 2 && base <= 36 );
    std::string results;
    while ( value != 0 || results.size() < minSize ) {
        results += digits[ value % base ];
        value /= base;
    }
    std::reverse( results.begin(), results.end() );
    return results;
}

如果需要,这允许固定格式。

您不需要预先计算数字:它很昂贵,并且不适用于负数。

由于您指定要查看 2 的补码表示,因此请对t使用unsigned long long以避免负数。

更改循环以继续除以 format,直到数字变为零,如下所示:

string toFormatFromDecimal(unsigned long long t, Format format) {
    string res = "";
    do {
        res += digits[(int) (t%format)];
        t = t/format;
    } while (t);
    return string(res.rbegin(), res.rend());
}

如果你的数字是负数,你必须做:

myNumber = Long.MAXVALUE + myNumber + 1;

之后设置most significant bit .

举个例子:假设你的长整型没有 64 位,只有 4 位。

You have the number -3 (1101)
number = 7 + (-3) + 1 = 5 (0101)

所以现在你有补码正数。如果你现在设置了最高有效位,你又有了负数:

("1"101) = -1

所以我的意思是,你可以计算出你的数字的正补码,你可以像你一样描述,现在你只需要确保,你最重要的十六进制是一个设置了第一个有效位的数字。因此,您必须在最重要的十六进制中添加 8。

例如,你计算正补码数的4FFA,你只需要把它改成CFFA,因为C = 4 + 8

对于十六进制变体,只使用 std::istringstream 和普通流格式怎么样?

喜欢

std::string toHexFromDecimal(long long t) {
    std::istringstream is;
    is << std::hex << t;
    return t.str();
}

对于二进制,像这样的东西怎么样:

std::string toBinFromDecimal(long long t) {
    std::string s;
    for (int bit = sizeof(t) * 8 - 1; bit >= 0; --bit) {
        s += '0' + (t >> bit) & 1;
    }
    return s;
}