我有这段代码:
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);
}
这应该将long long转换为hex或binary表示,这适用于所有可能的数字,但不适用于负数。
我是否可以扩展代码以处理已签名的数字? 谢谢Florian
编辑:现在我有相反的问题(String - &gt; long long)here
答案 0 :(得分:4)
要转换签名值,只需将输入转换为
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;
}
如果需要,这允许使用固定格式。
答案 1 :(得分:2)
您不需要预先计算数字:它代价高昂,而且不适用于负数。
由于您指定要查看二进制补码表示,因此请为unsigned long long
使用t
以避免否定。
更改循环以继续除以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());
}
答案 2 :(得分:1)
如果你的号码是否定的,你必须这样做:
myNumber = Long.MAXVALUE + myNumber + 1;
之后设置most significant bit
。
一个例子:假设,你的Long没有64位但只有4位。
You have the number -3 (1101)
number = 7 + (-3) + 1 = 5 (0101)
所以现在你有补数正数。如果您现在设置最重要的位,则会再次显示负数:
("1"101) = -1
所以我的意思是,你可以计算出你所描述的数字的正数补充,就像你所做的那样,现在你必须确保你最重要的十六进制数是一个数字第一个有效位设置。所以你必须在最重要的十六进制中加8。
E.g。您为正数补充数字计算4FFA
,只需将其更改为CFFA
,因为C = 4 + 8
。
答案 3 :(得分:0)
对于十六进制变体,如何使用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;
}