简体   繁体   English

在c ++中将long long转换为Hex和Binary

[英]Convert long long into Hex and Binary in c++

I have this code: 我有这个代码:

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);
}

This should convert long long into hex- or binary-representation, which works well for all possitive numbers, but doesn't with negative numbers. 这应该将long long转换为hex或binary表示,这适用于所有可能的数字,但不适用于负数。

Any ideas how I can extend my code to handle signed numbers as well? 任何想法我如何扩展我的代码来处理签名数字? Thanks Florian 谢谢弗洛里安

EDIT: Now I have a similar problem for the opposite (String -> long long) here 编辑:现在我有相反的类似的问题(字符串- >久长) 在这里

To convert the signed values, just convert your input to unsigned long long . 要转换签名值,只需将输入转换为unsigned long long Other than that: you don't need to establish a digit count, once you're dealing with an unsigned integral type, just continue until it is 0 . 除此之外:您无需建立数字计数,一旦处理无符号整数类型,就继续直到它为0 And to make sure you get at least one digit, even if the original value was 0 , use a do ... while loop: 并确保您至少获得一位数,即使原始值为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;

An often better solution is to pass the minimum number of digits in as an argument: 通常更好的解决方案是将最小位数作为参数传递:

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;
}

This allows fixed format, if desired. 如果需要,这允许固定格式。

You do not need to count digits upfront: it's costly, and it does not work for negative numbers. 您不需要预先计算数字:它的成本很高,而且对负数不起作用。

Since you specified that you would like to see a two's complement representation, use unsigned long long for your t to avoid negatives. 由于您曾表示希望看到一个二进制补码表示,使用unsigned long longt ,以避免负面影响。

Change your loop to continue dividing by format until the number gets to zero, like this: 更改循环以继续按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());
}

If your number is negative you must do: 如果您的电话号码是负数,则必须执行以下操作:

myNumber = Long.MAXVALUE + myNumber + 1;

After that set the most significant bit . 之后,设置most significant bit

An example: Assuming, your Long does not have 64 bit but only 4. 例如:假设您的Long没有64位,而只有4位。

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

So now you have the complement positive number. 因此,现在您有了补数正数。 If you now set the most significant bit you have your negative number again: 如果您现在设置最重要的位,则会再次显示负数:

("1"101) = -1

So what I mean is, you could calculate the positive complement of your number that you could describe like you did and now you just have to make sure, that your most significant hex is a number with the first significant bit set.So you have to add 8 to the most significant hex. 所以我的意思是,你可以计算出你所描述的数字的正补数,就像你所做的那样,现在你必须确保,你最重要的十六进制是一个第一个有效位设置的数字。所以你必须将8添加到最重要的十六进制。

Eg you calculate 4FFA for your positive complement number you just have to change it to CFFA , because C = 4 + 8 . 例如,您为正补数计算4FFA ,只需将其更改为CFFA ,因为C = 4 + 8

For the hexadecimal variant, how about just use std::istringstream and normal stream formatting? 对于十六进制变体,如何使用std::istringstream和普通流格式?

Like 喜欢

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

For binary, how about something like this: 对于二进制文件,如下所示:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM