将二进制转换为十六进制值(32位)

时间:2013-12-09 08:25:33

标签: c++ binary hex

我正在尝试将二进制值转换为十六进制值,我得到以下代码,它可以很好地工作到28位但不是32位。

代码如下。

int main()
{
    long int longint=0;
    string buf;
    cin>>buf;
    int len=buf.size();
    for(int i=0;i<len;i++)
    {
        longint+=( buf[len-i-1]-48) * pow((double)2,i);
    }
    cout<<setbase(16);
    cout<<longint;
    return 0;
}

如果输入28'1'(111111111111111111111111),则输出为fffffff 但如果我输入32'1'(11111111111111111111111111111111),则输出为80000000。

任何人都可以解释为什么会发生这种情况,也可以在上面的代码中解释为什么减去48。

5 个答案:

答案 0 :(得分:1)

问题似乎是使用pow,它使用浮点数学,如果我没记错的话。你可能遇到溢出问题。

计算2的幂的更优雅的方法是使用位移:

2^0 = 1 << 0 = 1
2^1 = 1 << 1 = 2
2^2 = 1 << 2 = 4
2^n = 1 << n

答案 1 :(得分:1)

作为Nathan的帖子,在更改代码时,它会显示正确,

longint += (buf[len-i-1]-'0') << i;

答案 2 :(得分:1)

您使用的是int32,当它用于32个字节时它超出范围,尝试使用int64即long long

    unsigned long long longint=0; //Change Here
    string buf;
    cin>>buf;
    int len=buf.length();
    for(int i=0;i<len;i++)
    {
        longint+=( buf[len-i-1]-48) * pow((double)2,i);
    }
    cout<<setbase(16);
    cout<<longint;

答案 3 :(得分:0)

  1. 这是因为您已强制将( buf[len-i-1]-48) * pow((double)2,i)
    转换为

    double 长度为8个字节,但它必须存储额外信息,因此无法完全充电以表示0x80000000,您可以找到更多信息{{ 3}}

    和你的上一个( buf[len-i-1]-48) * pow((double)2,i)
    (当我31岁时)表达已经溢出
    但是当从4294967295.0000000(这是0xffffffff)转换为int时它会发生一些问题,它只是出现了0x80000000 ,但我很抱歉我不知道为什么(请参考TonyK的评论)。<登记/>
    您可以将其更改为

    longint + =(long int)((buf [len-i-1] -48)* pow(2,i));

  2. 为什么减48?
    因为'0'的ascii是48,你想要从文字'0'转换为数字0,你必须这样做。

答案 4 :(得分:0)

原因是浮点值具有极限精度,而pow()计算机使用的数值计算近似值并不一定精确。要获得精确值,您应该使用逐位“&gt;&gt;”代替。

你可以看到pow()函数如何工作如下。

我改变了你的代码

  

longint + =(buf [len-i-1] -48)* pow((double)2,i)

到下面的代码,相等,因为pow()返回一个double值。

double temp = ( buf[len-i-1]-48) * pow((double)2,i);
longint+= temp;
cout<<setbase(16);
cout<<"temp"<<endl;
cout<<temp<<endl;
cout<<longint<<endl;

输出如下

temp
1.34218e+08
fffffff
temp
2.68435e+08
1fffffff
temp
5.36871e+08
3fffffff
temp
1.07374e+09
7fffffff
temp
2.14748e+09
80000000
final
80000000

其中显示pow()的精确度有限。 2.14748e+09不等于(2 ^ 31)。

你应该使用“&gt;&gt;”这是最好的或只是使用转换为整数,也不是100%相关。

您可以看到如下转换。

当我改变时

  

double temp =(buf [len-i-1] -48)* pow((double)2,i);

  

int temp =(buf [len-i-1] -48)* pow((double)2,i);

结果是

temp
8000000
fffffff
temp
10000000
1fffffff
temp
20000000
3fffffff
temp
40000000
7fffffff
temp
80000000
ffffffff
final
ffffffff

哪种方法正常。

减去48 你从标准输入中得到一个字符,例如,你从终端得到'1'而不是1.为了得到1.你应该使用'1' - '0'。 原因是:计算机存储'0'~'9'作为一个具有值的字节(48~57)。结果,'1' - '0'等于'1' - 48。