如何将很长的二进制数转换为十进制? [英] How do I convert a very long binary number to decimal?

查看:193
本文介绍了如何将很长的二进制数转换为十进制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个表示为11.1111111的二进制数字(.类似于小数点).该点之前有2位,而该点之后有1024位.这是在高精度地计算e时的一种练习,但是现在我对如何将e转换为小数感到困惑. 万一你们想知道这个数字,这里是:

I have a binary number represented as 11.1111111 (the . being analogous to a decimal point). There are 2 bits before the point, and 1024 bits after the point. It was an exercise in calculating e to a high level of precision, but now I am stuck as to how to convert it to decimal. Just in case you guys want to know the number, here it is:

10.1011011111100001010100010110001010001010111011010010101001101010101111110111000101011000100000001001110011110100111100111100011101100010111001110001011000001111001110001011010011011010010101101010011110000100110110010000010001010001100100001100111111101111001100100100111001110111001110001001001001101100111110111110010111110100101111111000110110001101100011000011000111010111011000111101101000000110110010000000101010111011000100011000010111101011010011110111110001111011010101110101011111110101100101011000010010010000110011111101010001111101011111000001100110111011010000100001010110001101100101010101010011110111101101000110101111001110110101010101110001001101011110011111110101011111001001001101011001100001001111000011000111000011100000111001101000101101110111111000101010011010001001110110101111001111101111111010000111001000011101111100010101100010100001001101101010110111100111001101010011000010101100110010100100111101001000001110100111100101111010101111000000101010110001100000101011001100100100111110110011101011

如何将其转换为2.718 ....(小数点后应有309位左右) 我不能简单地将每个位乘以2 ^ x,因为过一会儿,即使使用双精度浮点数,数字2 ^ x也将等于0.我正在使用Visual Basic,所以不确定是否存在任何较大的变量.

How do I convert this to 2.718.... (there should be about 309 digits after the decimal point) I can't simply multiply each bit by 2^x because after a while, the number 2^x will = 0, even when using a double precision float. I'm using Visual Basic, so I'm not sure there are any larger variables exist.

[由Spektre编辑]

只需将您的字符串与我的代码一起运行(基于我评论中的链接),结果就是:

Just have run your string with my code (based on the link in my comment) and the result is:

e(bigdecimal)=2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193200305992181741359662904357290033429526059563073813232862794349076323382988075319525101901157383418793070215408914993488416750924476146066808226480016847741185374234544243710753907774499206955170189257927265177296267786175561825444670874889747782175809270565601486538810885558129926100522647929865142359038501319247028975364903531383896590857864585070203793060262761378008328322397393650711101939331201
e      (text)=2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193200305992181741359662904357290033429526059563073813232862794349076323382988075319525101901157383418793070215408914993488416750924476146066808226480016847741185374234544243710753907774499206955170189
e (reference)=2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003059921817413596629043572900334295260595630738132328627943490763233829880753195251019011573834187930702154089149934884167509244761460668082264800168477411853742345442437107539077744992069551702761838606261331384583000752044933826560297606737113200709328709127443747047230696977209310141692836819025515108657463772111252389784425056953696770785449969967946864454905987931636889230098793127736178215424999229576351482208269895193668033182528869398496465105820939239829488793320362509443117301238197068416140397019837679320683282376464804295311802328782509819455815301756717361332069811250996181881593041690351598888519345807273866738589422879228499892086805825749279610484198444363463244968487560233624827041978623209002160990235304369941849146314093431738143640546253152096183690888707016768396424378140592714563549061303107208510383750510115747704171898610687396965521267154688957035035402123407849819334321068170121005627880235193033224745015853904730419957777093503660416997329725088687696640355570716226844716256079882651787134195124665201030592123667719432527867539855894489697096409754591856956380236370162112047742722836489613422516445078182442352948636372141740238893441247963574370263755294448337998016125492278509257782562092622648326277933386566481627725164019105900491644998289315056604725802778631864155195653244258698294695930801915298721172556347546396447910145904090586298496791287406870504895858671747985466775757320568128845920541334053922000113786300945560688166740016984205580403363795376452030402432256613527836951177883863874439662532249850654995886234281899707733276171783928034946501434558897071942586398772754710962953741521115136835062752602326484728703920764310059584116612054529703023647254929666938115137322753645098889031360205724817658511806303644281231496550704751025446501172721155519486685080036853228183152196003735625279449515828418829478761085263981395599006737648292244375287184624578036192981971399147564488262603903381441823262515097482798777996437308997038886778227138360577297882412561190717663946507063304527954661855096666185664709711344474016070462621568071748187784437143698821855967095910259686200235371858874856965220005031173439207321139080329363447972735595527734907178379342163701205005451326383544000186323991490705479778056697853358048966906295119432473099587655236812859041383241160722602998330535370876138939639177957454016137223618789365260538155841587186925538606164779834025435128

第一个是从文本转换为我的arbnum数据类型,然后转换回文本,中间是将纯文本转换为文本(例如,在链接之前先转换为十六进制),最后一个是参考e

The first is converted from text to my arbnum data-type and then converted back to text, middle is pure text to text conversion (like in the link with conversion to hex prior to that) and last is reference e

以下是您的二进制字符串的十六进制字符串:

Here the hex string of your binary string:

e (hex)      =2.B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF324E7738926CFBE5F4BF8D8D8C31D763DA06C80ABB1185EB4F7C7B5757F5958490CFD47D7C19BB42158D9554F7B46BCED55C4D79FD5F24D6613C31C3839A2DDF8A9A276BCFBFA1C877C56284DAB79CD4C2B3293D20E9E5EAF02AC60ACC93ECEBh

我将其截断为十进制半字节大小,因此最后可能剩下1,2或3位未处理...

I truncated down do decimal nibble sizes so there may be left 1,2 or 3 bits unprocessed at the end ...

推荐答案

  1. 将您的二进制字符串转换为十六进制

整数部分很容易"10." -> "2."小数部分也很容易:

the integer part is easy "10." -> "2." the fractional part is also easy:

10.1011011111100001010100010110 bin
10.1011 0111 1110 0001 0101 0001 0110 bin
 2.B    7    E    1    5    1    6    hex

如您所见,每个nibel整数值也是十六进制数字0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F这里是一些C ++代码:

as you can see each nibel integer value is also the hex digit 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F Here some C++ code:

int i,j,l; char *t16="0123456789ABCDEF";
AnsiString s0="10.your binary number",s1="2.";
for (i=4,l=s0.Length();i<=l;)
    {
    j=0;
    if ((i<=l)&&(s0[i]=='1')) j+=8; i++;
    if ((i<=l)&&(s0[i]=='1')) j+=4; i++;
    if ((i<=l)&&(s0[i]=='1')) j+=2; i++;
    if ((i<=l)&&(s0[i]=='1')) j+=1; i++;
    s1+=char(t16[j]);
    } // here s1 holds the hex string

通过预分配生成的s1大小,可以大大提高速度

this can be significantly speed-up by preallocationg the resulting s1 size

运行hex to dec字符串转换

run hex to dec string conversion

AnsiString str_hex2dec(const AnsiString &hex)
    {
    char c;
    AnsiString dec="",s;
    int i,j,l,ll,cy,val;
    int  i0,i1,i2,i3,sig;
    sig=+1; l=hex.Length();
    if (l) { c=hex[l]; if (c=='h') l--; if (c=='H') l--; }
    i0=0; i1=l; i2=0; i3=l;
    for (i=1;i<=l;i++)      // scan for parts of number
        {
        char c=hex[i];
        if (c=='-') sig=-sig;
        if ((c=='.')||(c==',')) i1=i-1;
        if ((c>='0')&&(c<='9')) { if (!i0) i0=i; if ((!i2)&&(i>i1)) i2=i; }
        if ((c>='A')&&(c<='F')) { if (!i0) i0=i; if ((!i2)&&(i>i1)) i2=i; }
        if ((c>='a')&&(c<='f')) { if (!i0) i0=i; if ((!i2)&&(i>i1)) i2=i; }
        }

    l=0; s=""; if (i0) for (i=i0;i<=i1;i++)
        {
        c=hex[i];
             if ((c>='0')&&(c<='9')) c-='0';
        else if ((c>='A')&&(c<='F')) c-='A'-10;
        else if ((c>='a')&&(c<='f')) c-='A'-10;
        for (cy=c,j=1;j<=l;j++)
            {
            val=(s[j]<<4)+cy;
            s[j]=val%10;
            cy  =val/10;
            }
        while (cy>0)
            {
            l++;
            s+=char(cy%10);
            cy/=10;
            }
        }
    if (s!="")
        {
        for (j=1;j<=l;j++) { c=s[j]; if (c<10) c+='0'; else c+='A'-10; s[j]=c; }
        for (i=l,j=1;j<i;j++,i--) { c=s[i]; s[i]=s[j]; s[j]=c; }
        dec+=s;
        }
    if (dec=="") dec="0";
    if (sig<0) dec="-"+dec;

    if (i2)
        {
        dec+='.';
        s=hex.SubString(i2,i3-i2+1);
        l=s.Length();
        for (i=1;i<=l;i++)
            {
            c=s[i];
                 if ((c>='0')&&(c<='9')) c-='0';
            else if ((c>='A')&&(c<='F')) c-='A'-10;
            else if ((c>='a')&&(c<='f')) c-='A'-10;
            s[i]=c;
            }
        ll=((l*1234)>>10);  // num of decimals to compute
        for (cy=0,i=1;i<=ll;i++)
            {
            for (cy=0,j=l;j>=1;j--)
                {
                val=s[j];
                val*=10;
                val+=cy;
                s[j]=val&15;
                cy=val>>4;
                }
            dec+=char(cy+'0');
            for (;;)
                {
                if (!l) break;;
                if (s[l]) break;
                l--;
                }
            if (!l) break;;
            }
        }

    return dec;
    }

此C ++/VCL代码基于决定在C ++中进行十六进制字符串转换或从中进行十六进制字符串转换

This C++/VCL code is based on dec to/from hex string conversion in C++

这里有一些完整的结果(不会被截断):

Here some full results (no truncating):

e (number)=2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517018925792726517729626778617556182544467087488974778217580927056560148653881088555812992610052264792986514235903850131924702897536490353138389659085786458507020379306026276137800832832239739365071110193933120100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
e (text)  =2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003059921817413596629043572900334295260595630738132328627943490763233829880753195251019011573834187930702154089149934884167509244761460668082264800168477411853742345442437107539077744992069551701892
e (const) =2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003059921817413596629043572900334295260595630738132328627943490763233829880753195251019011573834187930702154089149934884167509244761460668082264800168477411853742345442437107539077744992069551702761838606261331384583000752044933826560297606737113200709328709127443747047230696977209310141692836819025515108657463772111252389784425056953696770785449969967946864454905987931636889230098793127736178215424999229576351482208269895193668033182528869398496465105820939239829488793320362509443117301238197068416140397019837679320683282376464804295311802328782509819455815301756717361332069811250996181881593041690351598888519345807273866738589422879228499892086805825749279610484198444363463244968487560233624827041978623209002160990235304369941849146314093431738143640546253152096183690888707016768396424378140592714563549061303107208510383750510115747704171898610687396965521267154688957035035402123407849819334321068170121005627880235193033224745015853904730419957777093503660416997329725088687696640355570716226844716256079882651787134195124665201030592123667719432527867539855894489697096409754591856956380236370162112047742722836489613422516445078182442352948636372141740238893441247963574370263755294448337998016125492278509257782562092622648326277933386566481627725164019105900491644998289315056604725802778631864155195653244258698294695930801915298721172556347546396447910145904090586298496791287406870504895858671747985466775757320568128845920541334053922000113786300945560688166740016984205580403363795376452030402432256613527836951177883863874439662532249850654995886234281899707733276171783928034946501434558897071942586398772754710962953741521115136835062752602326484728703920764310059584116612054529703023647254929666938115137322753645098889031360205724817658511806303644281231496550704751025446501172721155519486685080036853228183152196003735625279449515828418829478761085263981395599006737648292244375287184624578036192981971399147564488262603903381441823262515097482798777996437308997038886778227138360577297882412561190717663946507063304527954661855096666185664709711344474016070462621568071748187784437143698821855967095910259686200235371858874856965220005031173439207321139080329363447972735595527734907178379342163701205005451326383544000186323991490705479778056697853358048966906295119432473099587655236812859041383241160722602998330535370876138939639177957454016137223618789365260538155841587186925538606164779834025435128
e (hex)   =2.B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF324E7738926CFBE5F4BF8D8D8C31D763DA06C80ABB1185EB4F7C7B5757F5958490CFD47D7C19BB42158D9554F7B46BCED55C4D79FD5F24D6613C31C3839A2DDF8A9A276BCFBFA1C877C56284DAB79CD4C2B3293D20E9E5EAF02AC60ACC93ECEBh

AnsiString只是具有自动重新分配功能的 VCL 字符串类,因此您只需通过+,+=运算符即可添加字符串...

The AnsiString is just VCL string class with automatic reallocation so you can add strings simply by +,+= operator ...

[edit1] hex2dec字符串转换的说明

好吧,我们有一个hex字符串,其中包含十六进制格式的数字,并且想要计算dec,该字符串最后应保留十进制格式的相同数字.

Ok we have hex string containing number in hex format and want to compute dec which should hold the same number in decimal format at the end.

  1. 扫描部分数字

这仅用一个O(n)循环扫描hex字符串,并记住特殊字符在哪里:

This just scans the hex string with single O(n) loop and remember where special characters are:

  • i0第一个整数
  • i1最后一个整数(小数点前)
  • i2第一个小数位数(小数点后)
  • i3最后一个小数位
  • 从头开始将
  • sig设置为+1,如果检测到-,则将其设置为-1表示数字的符号
  • i0 first integer digit
  • i1 last integer digit (before decimal point)
  • i2 first fractional digit (after decimal point)
  • i3 last fractional digit
  • sig is set to +1 from start and if - is detected then it is set to -1 means the sign of number

因此我们可以将后者用于更简单的数字提取.

So we can use that latter for simpler number extraction.

转换整数部分

整数部分是通过对十六进制数字值求和来计算的,例如:

integer part is computed by summing the hex digit values for example:

  • 51Ah = 500h + 10h + Ah = 5*16^2 + 1*16^1 + 10*16^0 = 1306

通常是这样重写的:

  • 51Ah = (((5)*16 +1)*16 +10) = 1306

您可以认为这就像您在源BASE(10)算术中将数字乘以目标BASE(16)一样.

You can think of that like you are multiplying number by target BASE(16) in source BASE(10) arithmetics.

因此,您首先要从最高有效位开始读取.将其值加到数字上.如果没有其他整数,则停止,否则将十进制字符串乘以16,然后读取/添加下一个数字.那就是第二个for循环的作用.

So you start read from the most significant digit first. Add its value to number. If no other integer digit present you stop otherwise multiply the decadic string by 16 and read/add next digit. That is what the second for loop does.

  • if (i0) for (i=i0;i<=i1;i++)如果存在整数部分,则通过其所有数字

  • if (i0) for (i=i0;i<=i1;i++) if integer part present go through all its digits

c设置为已处理数字<0,F>hex -> <0,15>dec

嵌套的for (cy=c,j=1;j<=l;j++)只是将整数十进制字符串s16相乘.在s=""; l=0;的开头,其中s是十进制结果字符串,但以相反的数字顺序且未以ASCII编码,而是直接存在数字值,因此{0,1,2,...9}而不是{"0","1",...},而ls. VCL字符串是从1索引的,这就是为什么for1而不是0开头的原因.那么如何将十进制字符串乘以16?

The nested for (cy=c,j=1;j<=l;j++) is just multiplying integer decadic string s by 16. At the start s=""; l=0; where s is decadic result string but in reverse digit order and not coded in ASCII instead values of digits are there directly so {0,1,2,...9} instead of {"0","1",...} and l is number of digits inside s. VCL string are indexed from 1 so that is why for starts with 1 not 0. So how you multiply decadic string by 16?

123*16= 100*16 +  20*16 +  3*16
      =1600    + 320    + 48

因此再次将十进制数字值<0,9>(从最低有效位开始)读入val.将其乘以16(或将<<4*16相同的位向左移4位),并在需要时将前一位的进位cy加起来(从开始就设置为十六进制值,因此它还要加上...).现在结果通常超过1位数,这就是进位的位置.因此,将s的结果位数设置为s[j]=val%10,将进位设置为val/10,则可以忽略10^(j-1),因为在处理s [j]时,10的幂由j位置表示,因此如果存储回s [j],该数字的值已加电...必须从最低有效数字开始,因为较高的数字在计算时仍在变化.

So again read digit decadic value <0,9> (start with least significant one) into val. Multiply it by 16 (or bit-shift left by 4 bits that <<4 is the same as *16 ) and add the carry cy from previous digit if needed (it is set to the hex digit value from start so it also add that ...). now the result is usually more than 1 digit that is where carry goes. So set the resulting digit of s to s[j]=val%10 and set carry to val/10 you can ignore the 10^(j-1) because when you are processing s[j] the powers of 10 are represented by j position so if you store back to s[j] the value of that digit is already powered... This must be done from least significant digit because the higher digits are still changing while computing.

在此之后,如果结果需要另外的一位,则while (cy>0)会向s添加新数字.

After this the while (cy>0) is just adding new digits to s if result needs additional one to fit in.

仅在s之后将其按常规顺序从数字值转换为ASCII(不再反转),并复制到最终的dec字符串中,并在需要时添加符号.这就是整数部分.

After this is just s converted from digit values to ASCII in normal order (not reversed anymore) copied to final dec string and signum added if needed. That is all for integer part.

小数部分以if (i2)

fractional part starts with if (i2)

通过将源基础BASE(16)算术中的目标BASE(10)乘以分数,可以将其转换为另一个BASE.所以用10=Ah乘以六进制算术...

Fractions are converted to another BASE by multiplying it by target BASE(10) in source BASE(16) arithmetic. So multiply by 10=Ah in hexa arithmetics ...

    ------------
    0.B7Eh -> B7Eh
    ------------
    B7Eh * Ah = 7 2ECh
    2ECh * Ah = 1 D38h
    D38h * Ah = 8 430h
    430h * Ah = 2 9E0h
    -------------
    0.B7Eh -> 0.7182 dec
    ------------

如果存在小数部分,则添加到最后的dec字符串小数点.中.并将所有小数十六进制数字提取到s字符串中(最高有效数字在前),从ASCII转换为十六进制数字值<0,15>,并将l设置为小数位数.然后计算ll,它是由l六进制小数ll=l*1234/1024表示的十进制小数位数.如您在示例中所见,有时可以无限次循环进行转换,以生成新的小数位数,因此ll停止...

OK if fractional part is present add to the final dec string decimal point .. And extract all fractional hex digits into s string (most significant digit first) convert from ASCII to hex digit values <0,15> and set l to number of fractional digits. the ll is then computed which is the number of decimal fractional digits represented by l hexa fractional digits ll=l*1234/1024 As you can see on the example you can sometimes loop the conversion infinitely generating new fractional digits so ll tels when to stop...

ll计算之后,转换开始. for (cy=0,i=1;i<=ll;i++)只是循环遍历所有结果数字以进行计算.在每次迭代中,s都乘以10,但这一次是十六进制算术.这就是为什么s[j]=val%16cy=val/16的原因.我改用位运算ANDBit-shift,但结果是相同的.乘法后,进位包含十进制小数位,因此将其添加到最终结果中.

The conversion starts after the ll computation. for (cy=0,i=1;i<=ll;i++) is just looping through all the result digits to compute. In each its iteration the s is multiplied by 10 but this time in hex arithmetics. That is why s[j]=val%16 and cy=val/16. I use bit operations AND and Bit-shift instead but the result is the same. After the multiplication the carry contains the decimal fractional digit so it is added to the final result.

最后一个for仅检查s中的子结果是否不以零结尾,是否将其截断(由l--终止),以及是否没有剩余的有效数字来停止该过程.这极大地加快了整个过程的速度...

The last for just check if the subresult in s is not ending with zeros and if it is it cut them off (by l--) and if no more valid digits left stop the process. This speed up the process a lot for huge numbers...

希望它对您足够描述...

Hope it is described enough for you...

这篇关于如何将很长的二进制数转换为十进制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆