简体   繁体   English

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

[英]Convert binary to hex value (32 bits)

i am trying to convert binary value as hex value and i got the following code and it is working well up to 28 bit but not for 32 bit. 我正在尝试将二进制值转换为十六进制值,我得到了以下代码,它在高达28位的情况下工作良好,但对于32位却没有。

The code is as follows. 代码如下。

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

If I input 28 '1' (111111111111111111111111) then the output is fffffff but if i input 32 '1' (11111111111111111111111111111111) then the output is 80000000. 如果我输入28'1'(111111111111111111111111),则输出为fffffff,但如果我输入32'1'(11111111111111111111111111111111111),则输出为80000000。

Can anyone please explain why this is happenning and also in the above code why 48 is subtracted . 任何人都可以解释为什么发生这种情况,以及在上面的代码中为什么要减去48。

The problem seems to be with the use of pow , which uses floating-point math, if I recall correctly.. You may be running into issues with overflow. 问题似乎出在pow的使用上,如果我没pow ,它使用浮点数学运算。您可能会遇到溢出问题。

A more elegant way to calculate powers of two is by using bit-shifts: 一种计算二的幂的更优雅的方法是使用移位:

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

如内森(Nathan)的帖子,当您更改代码时,它将显示正确,

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

You are using int32 and it is getting out of range when you use it for 32 bytes,try using int64 ie long long 您正在使用int32,当您使用int32时,它超出了范围,请尝试使用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;
  1. This is because you have forced 这是因为你强迫
    ( buf[len-i-1]-48) * pow((double)2,i)
    to be converted to double , 要转换为double

    and double is 8 bytes long, 并且 double是8个字节长,
    but it has to store extra information, 但它必须存储更多信息,
    it can not be full charged to represent 0x80000000, 它不能充满以表示0x80000000,
    you can find more information here 您可以 在这里找到更多信息

    and your last 还有你的最后一个
    ( buf[len-i-1]-48) * pow((double)2,i)
    (when i is 31) expression already overflow . (我31岁时)表达式已经 溢出
    But something weard happend when converting from 4294967295.0000000(which is 0xffffffff) to int , it just come out 0x80000000 , but I am very sorry I don't know why(Please reference the comment from TonyK). 但是,当从4294967295.0000000(即0xffffffff)转换为int时,发生了一些变化,它只是输出0x80000000 ,但是很抱歉,我不知道为什么(请参考TonyK的评论)。

    You can change it to 您可以将其更改为

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

  2. Why minus 48 ? 为什么要减48?
    because ascii for '0' is 48, you want to convert from literal '0' to numeric 0, you have to do it. 因为'0'的ascii为48,所以您要从文字'0'转换为数字0,所以必须这样做。

The reason is that float-value is with limit precision and pow() computer use numerical calculation approximation which isn't definitely precise. 原因是浮点值具有极限精度,pow()计算机使用的数值计算近似值不一定精确。 To get a precise value, you should use bit-wise ">>" instead. 要获得精确值,您应该改用按位“ >>”。

You can see how pow() function works as below. 您可以看到pow()函数的工作方式如下。

I changed your code 我更改了您的代码

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

to the code below, which is equal, becase pow() return a double value. 与下面的代码相等,如果pow()返回一个双精度值。

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;

the output is as below 输出如下

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

Which shows clearly pow() is with limited precision. 这清楚地表明pow()的精度有限。 2.14748e+09 is not equal to (2^31). 2.14748e+09不等于(2 ^ 31)。

You should use ">>" which is the best or just use conversion to integer which isn't 100 percently correclty, either. 您应该使用最好的“ >>”,或者只使用转换成不是100%正确的整数。

You can see conversion as below. 您可以看到如下所示的转换。

when I change 当我改变

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

to

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

the result is 结果是

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

Which works correctly. 哪个工作正常。

substract 48 You got a char from standard input, for example, you got '1' from terminal instead of 1. In order to get 1. You should use '1'-'0'. 减去48您从标准输入中获得了一个字符,例如,从终端而不是1中获得了“ 1”。为了获得1,您应使用“ 1”-“ 0”。 The reason : computer store '0'~'9' as a byte with value(48~57). 原因:计算机将“ 0”〜“ 9”存储为值(48〜57)的字节。 As a result, '1' - '0' equals '1' - 48. 结果,“ 1”-“ 0”等于“ 1”-48。

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

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